From 4a7248cfa9fdcab15b144f08ff97497ec5ab85d4 Mon Sep 17 00:00:00 2001 From: thibaud-lclr Date: Tue, 12 May 2026 10:30:11 +0200 Subject: [PATCH] feat(bootstrap): add DisabledCommands option to hide unused commands Commands listed in DisabledCommands are excluded from global help output and return ErrUnknownCommand when invoked or help is requested for them. Co-Authored-By: Claude Sonnet 4.6 --- bootstrap/bootstrap.go | 43 +++++++++++++++++++++-------- bootstrap/bootstrap_test.go | 55 +++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 11 deletions(-) diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index 2ee682f..e7f1d03 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -52,17 +52,18 @@ type Hooks struct { } type Options struct { - BinaryName string - Description string - Version string - Aliases map[string][]string - AliasDescriptions map[string]string - EnableDoctorAlias bool - Args []string - Stdin io.Reader - Stdout io.Writer - Stderr io.Writer - Hooks Hooks + BinaryName string + Description string + Version string + Aliases map[string][]string + AliasDescriptions map[string]string + EnableDoctorAlias bool + DisabledCommands []string + Args []string + Stdin io.Reader + Stdout io.Writer + Stderr io.Writer + Hooks Hooks } type Invocation struct { @@ -146,6 +147,10 @@ func Run(ctx context.Context, opts Options) error { return printHelp(normalized, "") } + if isCommandDisabled(command, normalized.DisabledCommands) { + return fmt.Errorf("%w: %s", ErrUnknownCommand, command) + } + if command == CommandConfig { return runConfigCommand(ctx, normalized, commandArgs) } @@ -460,6 +465,10 @@ func printHelp(opts Options, command string, args ...[]string) error { return printConfigHelp(opts, commandArgs) } + if isCommandDisabled(command, opts.DisabledCommands) { + return fmt.Errorf("%w: %s", ErrUnknownCommand, command) + } + for _, def := range commands { if def.Name != command { continue @@ -535,6 +544,9 @@ func printGlobalHelp(opts Options) error { } for _, def := range commands { + if isCommandDisabled(def.Name, opts.DisabledCommands) { + continue + } if _, err := fmt.Fprintf(opts.Stdout, " %-7s %s\n", def.Name, def.Description); err != nil { return err } @@ -571,6 +583,15 @@ func printGlobalHelp(opts Options) error { return err } +func isCommandDisabled(command string, disabled []string) bool { + for _, d := range disabled { + if d == command { + return true + } + } + return false +} + func aliasDescription(descriptions map[string]string, name, target string) string { description := strings.TrimSpace(descriptions[name]) if description == "" { diff --git a/bootstrap/bootstrap_test.go b/bootstrap/bootstrap_test.go index ca2c34a..f0fbbeb 100644 --- a/bootstrap/bootstrap_test.go +++ b/bootstrap/bootstrap_test.go @@ -607,3 +607,58 @@ func TestRunAcceptsGlobalDebugFlagAfterCommand(t *testing.T) { t.Fatalf("MCP_FRAMEWORK_BITWARDEN_DEBUG = %q, want %q", os.Getenv("MCP_FRAMEWORK_BITWARDEN_DEBUG"), "1") } } + +func TestDisabledCommandReturnsUnknown(t *testing.T) { + var stdout bytes.Buffer + var stderr bytes.Buffer + + err := Run(context.Background(), Options{ + BinaryName: "my-mcp", + Args: []string{"login"}, + DisabledCommands: []string{"login"}, + Stdout: &stdout, + Stderr: &stderr, + }) + + if !errors.Is(err, ErrUnknownCommand) { + t.Fatalf("err = %v, want ErrUnknownCommand", err) + } +} + +func TestDisabledCommandHiddenFromHelp(t *testing.T) { + var stdout bytes.Buffer + + err := printGlobalHelp(Options{ + BinaryName: "my-mcp", + DisabledCommands: []string{"login", "setup"}, + Stdout: &stdout, + }) + if err != nil { + t.Fatalf("printGlobalHelp error = %v", err) + } + + out := stdout.String() + if strings.Contains(out, "login") { + t.Fatalf("help should not contain disabled command %q, got:\n%s", "login", out) + } + if strings.Contains(out, "setup") { + t.Fatalf("help should not contain disabled command %q, got:\n%s", "setup", out) + } + if !strings.Contains(out, "mcp") { + t.Fatalf("help should contain enabled command %q, got:\n%s", "mcp", out) + } +} + +func TestDisabledCommandHelpReturnsUnknown(t *testing.T) { + var stdout bytes.Buffer + + err := printHelp(Options{ + BinaryName: "my-mcp", + DisabledCommands: []string{"login"}, + Stdout: &stdout, + }, "login") + + if !errors.Is(err, ErrUnknownCommand) { + t.Fatalf("err = %v, want ErrUnknownCommand", err) + } +}