From e18bfeec914c79c397a30a89a32fad1d0dafdb44 Mon Sep 17 00:00:00 2001 From: xli-oai Date: Thu, 23 Apr 2026 09:48:37 -0700 Subject: [PATCH] [codex] Fix plugin marketplace help usage (#18710) ## Summary - Updates generated CLI help for plugin marketplace commands to show the full `codex plugin marketplace ...` namespace. - Adds a regression test covering the marketplace command and its `add`, `upgrade`, and `remove` help pages. ## Root Cause The marketplace parser already lived under `codex plugin marketplace`, but Clap generated usage text from the child parser's standalone command name. That made help output show stale `codex marketplace ...` instructions even though the top-level `codex marketplace` command no longer parses. ## Validation - `just fmt` - `cargo test -p codex-cli` - `./target/debug/codex plugin marketplace --help` --- codex-rs/cli/src/main.rs | 25 +++++++++++++++++++++++++ codex-rs/cli/src/marketplace_cmd.rs | 4 ++++ 2 files changed, 29 insertions(+) diff --git a/codex-rs/cli/src/main.rs b/codex-rs/cli/src/main.rs index 9852a2cd5..3f4b018f1 100644 --- a/codex-rs/cli/src/main.rs +++ b/codex-rs/cli/src/main.rs @@ -176,6 +176,7 @@ enum Subcommand { } #[derive(Debug, Parser)] +#[command(bin_name = "codex plugin")] struct PluginCli { #[clap(flatten)] pub config_overrides: CliConfigOverrides, @@ -1773,6 +1774,30 @@ mod tests { assert!(matches!(cli.subcommand, Some(Subcommand::Responses(_)))); } + fn help_from_args(args: &[&str]) -> String { + let err = MultitoolCli::try_parse_from(args).expect_err("help should short-circuit"); + assert_eq!(err.kind(), clap::error::ErrorKind::DisplayHelp); + err.to_string() + } + + #[test] + fn plugin_marketplace_help_uses_plugin_namespace() { + let help = help_from_args(&["codex", "plugin", "marketplace", "--help"]); + assert!( + help.contains("Usage: codex plugin marketplace [OPTIONS] "), + "{help}" + ); + + for (subcommand, usage) in [ + ("add", "Usage: codex plugin marketplace add"), + ("upgrade", "Usage: codex plugin marketplace upgrade"), + ("remove", "Usage: codex plugin marketplace remove"), + ] { + let help = help_from_args(&["codex", "plugin", "marketplace", subcommand, "--help"]); + assert!(help.contains(usage), "{help}"); + } + } + #[test] fn plugin_marketplace_add_parses_under_plugin() { let cli = diff --git a/codex-rs/cli/src/marketplace_cmd.rs b/codex-rs/cli/src/marketplace_cmd.rs index a29f9ba76..5130e9ebc 100644 --- a/codex-rs/cli/src/marketplace_cmd.rs +++ b/codex-rs/cli/src/marketplace_cmd.rs @@ -13,6 +13,7 @@ use codex_core::plugins::remove_marketplace; use codex_utils_cli::CliConfigOverrides; #[derive(Debug, Parser)] +#[command(bin_name = "codex plugin marketplace")] pub struct MarketplaceCli { #[clap(flatten)] pub config_overrides: CliConfigOverrides, @@ -29,6 +30,7 @@ enum MarketplaceSubcommand { } #[derive(Debug, Parser)] +#[command(bin_name = "codex plugin marketplace add")] struct AddMarketplaceArgs { /// Marketplace source. Supports owner/repo[@ref], HTTP(S) Git URLs, SSH URLs, /// or local marketplace root directories. @@ -46,11 +48,13 @@ struct AddMarketplaceArgs { } #[derive(Debug, Parser)] +#[command(bin_name = "codex plugin marketplace upgrade")] struct UpgradeMarketplaceArgs { marketplace_name: Option, } #[derive(Debug, Parser)] +#[command(bin_name = "codex plugin marketplace remove")] struct RemoveMarketplaceArgs { /// Configured marketplace name to remove. marketplace_name: String,