From df8c5aaaed79a3a189cb47dbb2b35871269e9d07 Mon Sep 17 00:00:00 2001 From: OnlyYu1996 <1158673577@qq.com> Date: Sun, 17 May 2026 20:18:01 +0800 Subject: [PATCH] fix(cli): add verbose plugin enable diagnostics --- src/cortex-cli/src/agent_cmd/tests.rs | 5 +-- src/cortex-cli/src/cli/args.rs | 9 +++++ src/cortex-cli/src/cli/handlers.rs | 2 +- src/cortex-cli/src/plugin_cmd.rs | 56 +++++++++++++++++++++++++-- 4 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/cortex-cli/src/agent_cmd/tests.rs b/src/cortex-cli/src/agent_cmd/tests.rs index e2ff07f9f..18f7ba753 100644 --- a/src/cortex-cli/src/agent_cmd/tests.rs +++ b/src/cortex-cli/src/agent_cmd/tests.rs @@ -3,10 +3,9 @@ #[cfg(test)] mod tests { use crate::agent_cmd::cli::{CopyArgs, ExportArgs}; - use crate::agent_cmd::loader::{ - load_builtin_agents, parse_frontmatter, read_file_with_encoding, - }; + use crate::agent_cmd::loader::{load_builtin_agents, parse_frontmatter}; use crate::agent_cmd::types::AgentMode; + use crate::utils::file::read_file_with_encoding; #[test] fn test_read_file_with_utf8() { diff --git a/src/cortex-cli/src/cli/args.rs b/src/cortex-cli/src/cli/args.rs index 641d63a4a..3a5d4ff23 100644 --- a/src/cortex-cli/src/cli/args.rs +++ b/src/cortex-cli/src/cli/args.rs @@ -988,6 +988,15 @@ mod tests { assert!(cli.verbose); } + #[test] + fn test_cli_global_verbose_with_plugin_enable() { + let cli = Cli::try_parse_from(["cortex", "--verbose", "plugin", "enable", "sample-one"]) + .expect("should parse global --verbose with plugin enable"); + + assert!(cli.verbose); + assert!(matches!(cli.command, Some(Commands::Plugin(_)))); + } + #[test] fn test_cli_verbose_short_flag() { let cli = Cli::try_parse_from(["cortex", "-v"]).expect("should parse -v"); diff --git a/src/cortex-cli/src/cli/handlers.rs b/src/cortex-cli/src/cli/handlers.rs index e92fa8632..ec0c4da5c 100644 --- a/src/cortex-cli/src/cli/handlers.rs +++ b/src/cortex-cli/src/cli/handlers.rs @@ -58,7 +58,7 @@ pub async fn dispatch_command(cli: Cli) -> Result<()> { Some(Commands::Debug(debug_cli)) => debug_cli.run().await, Some(Commands::Servers(servers_cli)) => run_servers(servers_cli).await, Some(Commands::History(history_cli)) => run_history(history_cli).await, - Some(Commands::Plugin(plugin_cli)) => plugin_cli.run().await, + Some(Commands::Plugin(plugin_cli)) => plugin_cli.run(cli.verbose).await, Some(Commands::Feedback(feedback_cli)) => feedback_cli.run().await, Some(Commands::Lock(lock_cli)) => lock_cli.run().await, Some(Commands::Alias(alias_cli)) => alias_cli.run().await, diff --git a/src/cortex-cli/src/plugin_cmd.rs b/src/cortex-cli/src/plugin_cmd.rs index 3ce99f238..a511fcd75 100644 --- a/src/cortex-cli/src/plugin_cmd.rs +++ b/src/cortex-cli/src/plugin_cmd.rs @@ -939,12 +939,12 @@ cp plugin.toml ~/.cortex/plugins/{}/ impl PluginCli { /// Run the plugin command. - pub async fn run(self) -> Result<()> { + pub async fn run(self, verbose: bool) -> Result<()> { match self.subcommand { PluginSubcommand::List(args) => run_list(args).await, PluginSubcommand::Install(args) => run_install(args).await, PluginSubcommand::Remove(args) => run_remove(args).await, - PluginSubcommand::Enable(args) => run_enable(args).await, + PluginSubcommand::Enable(args) => run_enable(args, verbose).await, PluginSubcommand::Disable(args) => run_disable(args).await, PluginSubcommand::Show(args) => run_show(args).await, PluginSubcommand::New(args) => run_new(args).await, @@ -1169,7 +1169,30 @@ async fn run_remove(args: PluginRemoveArgs) -> Result<()> { Ok(()) } -async fn run_enable(args: PluginEnableArgs) -> Result<()> { +fn plugin_enabled_value(manifest: &toml::Value) -> Option { + manifest.get("enabled").and_then(|value| value.as_bool()) +} + +fn format_enable_verbose_output( + plugin_path: &Path, + manifest_path: &Path, + previous_enabled: Option, + current_enabled: bool, +) -> String { + let previous = previous_enabled + .map(|value| value.to_string()) + .unwrap_or_else(|| "not set".to_string()); + + format!( + " Plugin directory: {}\n Manifest path: {}\n Previous enabled: {}\n Current enabled: {}", + plugin_path.display(), + manifest_path.display(), + previous, + current_enabled + ) +} + +async fn run_enable(args: PluginEnableArgs, verbose: bool) -> Result<()> { let plugins_dir = get_plugins_dir(); let plugin_path = plugins_dir.join(&args.name); let manifest_path = plugin_path.join("plugin.toml"); @@ -1180,6 +1203,7 @@ async fn run_enable(args: PluginEnableArgs) -> Result<()> { let content = std::fs::read_to_string(&manifest_path)?; let mut manifest: toml::Value = toml::from_str(&content)?; + let previous_enabled = plugin_enabled_value(&manifest); if let Some(table) = manifest.as_table_mut() { table.insert("enabled".to_string(), toml::Value::Boolean(true)); @@ -1187,6 +1211,12 @@ async fn run_enable(args: PluginEnableArgs) -> Result<()> { std::fs::write(&manifest_path, toml::to_string_pretty(&manifest)?)?; println!("Plugin '{}' enabled.", args.name); + if verbose { + println!( + "{}", + format_enable_verbose_output(&plugin_path, &manifest_path, previous_enabled, true) + ); + } Ok(()) } @@ -2471,6 +2501,26 @@ mod tests { assert_eq!(args.name, "enable-me", "name should match"); } + #[test] + fn test_plugin_enable_verbose_output_adds_diagnostics() { + let plugin_path = PathBuf::from("/home/user/.cortex/plugins/sample-one"); + let manifest_path = plugin_path.join("plugin.toml"); + + let default_output = "Plugin 'sample-one' enabled.".to_string(); + let verbose_details = + format_enable_verbose_output(&plugin_path, &manifest_path, Some(false), true); + let verbose_output = format!("{default_output}\n{verbose_details}"); + + assert_ne!( + default_output, verbose_output, + "verbose enable output should differ from default output" + ); + assert!(verbose_output.contains("Plugin directory:")); + assert!(verbose_output.contains("Manifest path:")); + assert!(verbose_output.contains("Previous enabled: false")); + assert!(verbose_output.contains("Current enabled: true")); + } + #[test] fn test_plugin_disable_args() { let args = PluginDisableArgs {