diff --git a/internal/cmd/flags.go b/internal/cmd/flags.go index f0209b1d7..6a38b3293 100644 --- a/internal/cmd/flags.go +++ b/internal/cmd/flags.go @@ -57,25 +57,11 @@ func registerAllFlags(cmd *cobra.Command) { // registerFlagCompletions registers custom completion functions for flags func registerFlagCompletions(cmd *cobra.Command) { - // Custom completion for --config flag (complete with .toml files) - cmd.RegisterFlagCompletionFunc("config", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return []string{"toml"}, cobra.ShellCompDirectiveFilterFileExt - }) - - // Custom completion for --log-dir flag (complete with directories) - cmd.RegisterFlagCompletionFunc("log-dir", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return nil, cobra.ShellCompDirectiveFilterDirs - }) - - // Custom completion for --payload-dir flag (complete with directories) - cmd.RegisterFlagCompletionFunc("payload-dir", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return nil, cobra.ShellCompDirectiveFilterDirs - }) - - // Custom completion for --env flag (complete with .env files) - cmd.RegisterFlagCompletionFunc("env", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return []string{"env"}, cobra.ShellCompDirectiveFilterFileExt - }) + // File and directory completions using idiomatic cobra helpers + cmd.MarkFlagFilename("config", "toml") + cmd.MarkFlagDirname("log-dir") + cmd.MarkFlagDirname("payload-dir") + cmd.MarkFlagFilename("env", "env") // Enum completions for DIFC flags cmd.RegisterFlagCompletionFunc("guards-mode", cobra.FixedCompletions( diff --git a/internal/cmd/root.go b/internal/cmd/root.go index d1c95630c..f0d60c6f5 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -51,6 +51,7 @@ var rootCmd = &cobra.Command{ Version: cliVersion, Long: `MCPG is a proxy server for Model Context Protocol (MCP) servers. It provides routing, aggregation, and management of multiple MCP backend servers.`, + Args: cobra.NoArgs, SilenceUsage: true, // Don't show help on runtime errors SilenceErrors: true, // Prevent cobra from printing errors — Execute() caller handles display PersistentPreRunE: preRun, diff --git a/internal/cmd/root_test.go b/internal/cmd/root_test.go index bacd128e5..2fd94688d 100644 --- a/internal/cmd/root_test.go +++ b/internal/cmd/root_test.go @@ -40,7 +40,7 @@ func TestRunRequiresConfigSource(t *testing.T) { t.Run("config file provided", func(t *testing.T) { configFile = "test.toml" configStdin = false - err := preRun(nil, nil) + err := preRun(&cobra.Command{}, nil) // Should pass validation when --config is provided assert.NoError(t, err, "Should not error when --config is provided") }) @@ -48,7 +48,7 @@ func TestRunRequiresConfigSource(t *testing.T) { t.Run("config stdin provided", func(t *testing.T) { configFile = "" configStdin = true - err := preRun(nil, nil) + err := preRun(&cobra.Command{}, nil) // Should pass validation when --config-stdin is provided assert.NoError(t, err, "Should not error when --config-stdin is provided") }) @@ -56,7 +56,7 @@ func TestRunRequiresConfigSource(t *testing.T) { t.Run("both config file and stdin provided", func(t *testing.T) { configFile = "test.toml" configStdin = true - err := preRun(nil, nil) + err := preRun(&cobra.Command{}, nil) // When both are provided, should pass validation assert.NoError(t, err, "Should not error when both are provided") }) @@ -78,7 +78,7 @@ func TestPreRunValidation(t *testing.T) { configFile = "test.toml" configStdin = false verbosity = 0 - err := preRun(nil, nil) + err := preRun(&cobra.Command{}, nil) assert.NoError(t, err) }) @@ -86,7 +86,7 @@ func TestPreRunValidation(t *testing.T) { configFile = "" configStdin = true verbosity = 0 - err := preRun(nil, nil) + err := preRun(&cobra.Command{}, nil) assert.NoError(t, err) }) @@ -108,7 +108,7 @@ func TestPreRunValidation(t *testing.T) { configFile = "test.toml" configStdin = false verbosity = 1 - err := preRun(nil, nil) + err := preRun(&cobra.Command{}, nil) assert.NoError(t, err) // Level 1 doesn't set DEBUG env var assert.Empty(t, os.Getenv(logger.EnvDebug)) @@ -129,7 +129,7 @@ func TestPreRunValidation(t *testing.T) { configFile = "test.toml" configStdin = false verbosity = 2 - err := preRun(nil, nil) + err := preRun(&cobra.Command{}, nil) assert.NoError(t, err) assert.Equal(t, "cmd:*,server:*,launcher:*", os.Getenv(logger.EnvDebug)) }) @@ -149,7 +149,7 @@ func TestPreRunValidation(t *testing.T) { configFile = "test.toml" configStdin = false verbosity = 3 - err := preRun(nil, nil) + err := preRun(&cobra.Command{}, nil) assert.NoError(t, err) assert.Equal(t, "*", os.Getenv(logger.EnvDebug)) }) @@ -169,7 +169,7 @@ func TestPreRunValidation(t *testing.T) { configFile = "test.toml" configStdin = false verbosity = 2 - err := preRun(nil, nil) + err := preRun(&cobra.Command{}, nil) assert.NoError(t, err) // Should not override existing DEBUG assert.Equal(t, "custom:*", os.Getenv(logger.EnvDebug))