mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Add JSON output for plugin subcommands (#26631)
## Summary - Follow-up to #25330 and #26417 - Add `--json` output for `codex plugin add` and `codex plugin remove` - Add `--json` output for `codex plugin marketplace add/list/upgrade/remove` - Keep existing human-readable output unchanged - Keep existing error handling/stderr behavior unchanged; `--json` changes successful stdout output only - Align marketplace add/remove JSON field names with the existing app-server protocol shape - Add CLI coverage for plugin and marketplace JSON outputs ## Validation - `just fmt` - `just fix -p codex-cli` - `just test -p codex-cli`
This commit is contained in:
committed by
GitHub
Unverified
parent
055c7a7c53
commit
bb7d19bc24
@@ -6,6 +6,7 @@ use codex_core::config::Config;
|
||||
use codex_core::config::find_codex_home;
|
||||
use codex_core_plugins::ConfiguredMarketplace;
|
||||
use codex_core_plugins::OPENAI_BUNDLED_MARKETPLACE_NAME;
|
||||
use codex_core_plugins::PluginInstallOutcome;
|
||||
use codex_core_plugins::PluginInstallRequest;
|
||||
use codex_core_plugins::PluginsConfigInput;
|
||||
use codex_core_plugins::PluginsManager;
|
||||
@@ -73,6 +74,10 @@ pub struct AddPluginArgs {
|
||||
/// Configured marketplace name to use when PLUGIN does not include @MARKETPLACE.
|
||||
#[arg(long = "marketplace", short = 'm', value_name = "MARKETPLACE")]
|
||||
marketplace_name: Option<String>,
|
||||
|
||||
/// Output install result as JSON.
|
||||
#[arg(long = "json")]
|
||||
json: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
@@ -107,6 +112,10 @@ pub struct RemovePluginArgs {
|
||||
/// Marketplace name to use when PLUGIN does not include @MARKETPLACE.
|
||||
#[arg(long = "marketplace", short = 'm', value_name = "MARKETPLACE")]
|
||||
marketplace_name: Option<String>,
|
||||
|
||||
/// Output remove result as JSON.
|
||||
#[arg(long = "json")]
|
||||
json: bool,
|
||||
}
|
||||
|
||||
pub async fn run_plugin_add(
|
||||
@@ -118,11 +127,16 @@ pub async fn run_plugin_add(
|
||||
plugins_input,
|
||||
manager,
|
||||
} = load_plugin_command_context(overrides).await?;
|
||||
let AddPluginArgs {
|
||||
plugin,
|
||||
marketplace_name,
|
||||
json,
|
||||
} = args;
|
||||
let PluginSelection {
|
||||
plugin_name,
|
||||
marketplace_name,
|
||||
..
|
||||
} = parse_plugin_selection(args.plugin, args.marketplace_name)?;
|
||||
} = parse_plugin_selection(plugin, marketplace_name)?;
|
||||
let marketplace = find_marketplace_for_plugin(
|
||||
&manager,
|
||||
codex_home.as_path(),
|
||||
@@ -137,6 +151,12 @@ pub async fn run_plugin_add(
|
||||
})
|
||||
.await?;
|
||||
|
||||
if json {
|
||||
let output = JsonPluginAddOutput::from_outcome(outcome);
|
||||
println!("{}", serde_json::to_string_pretty(&output)?);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
println!(
|
||||
"Added plugin `{}` from marketplace `{}`.",
|
||||
outcome.plugin_id.plugin_name, outcome.plugin_id.marketplace_name
|
||||
@@ -149,6 +169,30 @@ pub async fn run_plugin_add(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct JsonPluginAddOutput {
|
||||
plugin_id: String,
|
||||
name: String,
|
||||
marketplace_name: String,
|
||||
version: String,
|
||||
installed_path: String,
|
||||
auth_policy: &'static str,
|
||||
}
|
||||
|
||||
impl JsonPluginAddOutput {
|
||||
fn from_outcome(outcome: PluginInstallOutcome) -> Self {
|
||||
Self {
|
||||
plugin_id: outcome.plugin_id.as_key(),
|
||||
name: outcome.plugin_id.plugin_name,
|
||||
marketplace_name: outcome.plugin_id.marketplace_name,
|
||||
version: outcome.plugin_version,
|
||||
installed_path: outcome.installed_path.as_path().display().to_string(),
|
||||
auth_policy: auth_policy_label(outcome.auth_policy),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run_plugin_list(
|
||||
overrides: Vec<(String, toml::Value)>,
|
||||
args: ListPluginsArgs,
|
||||
@@ -449,9 +493,22 @@ pub async fn run_plugin_remove(
|
||||
args: RemovePluginArgs,
|
||||
) -> Result<()> {
|
||||
let PluginCommandContext { manager, .. } = load_plugin_command_context(overrides).await?;
|
||||
let selection = parse_plugin_selection(args.plugin, args.marketplace_name)?;
|
||||
let RemovePluginArgs {
|
||||
plugin,
|
||||
marketplace_name,
|
||||
json,
|
||||
} = args;
|
||||
let selection = parse_plugin_selection(plugin, marketplace_name)?;
|
||||
|
||||
manager
|
||||
.uninstall_plugin(selection.plugin_key.clone())
|
||||
.await?;
|
||||
if json {
|
||||
let output = JsonPluginRemoveOutput::from_selection(selection);
|
||||
println!("{}", serde_json::to_string_pretty(&output)?);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
manager.uninstall_plugin(selection.plugin_key).await?;
|
||||
println!(
|
||||
"Removed plugin `{}` from marketplace `{}`.",
|
||||
selection.plugin_name, selection.marketplace_name
|
||||
@@ -460,6 +517,24 @@ pub async fn run_plugin_remove(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct JsonPluginRemoveOutput {
|
||||
plugin_id: String,
|
||||
name: String,
|
||||
marketplace_name: String,
|
||||
}
|
||||
|
||||
impl JsonPluginRemoveOutput {
|
||||
fn from_selection(selection: PluginSelection) -> Self {
|
||||
Self {
|
||||
plugin_id: selection.plugin_key,
|
||||
name: selection.plugin_name,
|
||||
marketplace_name: selection.marketplace_name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PluginCommandContext {
|
||||
codex_home: PathBuf,
|
||||
plugins_input: PluginsConfigInput,
|
||||
|
||||
Reference in New Issue
Block a user