diff --git a/codex-rs/core/src/plugins/manager.rs b/codex-rs/core/src/plugins/manager.rs index d2c4a0602a..c2db3a1de1 100644 --- a/codex-rs/core/src/plugins/manager.rs +++ b/codex-rs/core/src/plugins/manager.rs @@ -228,6 +228,47 @@ impl PluginLoadOutcome { } } +fn plugin_capability_summary_from_loaded_plugin( + plugin: &LoadedPlugin, +) -> Option { + if !plugin.is_active() { + return None; + } + + let mut mcp_server_names: Vec = plugin.mcp_servers.keys().cloned().collect(); + mcp_server_names.sort_unstable(); + + let summary = PluginCapabilitySummary { + config_name: plugin.config_name.clone(), + display_name: plugin + .manifest_name + .clone() + .unwrap_or_else(|| plugin.config_name.clone()), + description: prompt_safe_plugin_description(plugin.manifest_description.as_deref()), + has_skills: !plugin.skill_roots.is_empty(), + mcp_server_names, + app_connector_ids: plugin.apps.clone(), + }; + + (summary.has_skills + || !summary.mcp_server_names.is_empty() + || !summary.app_connector_ids.is_empty()) + .then_some(summary) +} + +impl From for PluginCapabilitySummary { + fn from(value: PluginDetailSummary) -> Self { + Self { + config_name: value.id, + display_name: value.name, + description: prompt_safe_plugin_description(value.description.as_deref()), + has_skills: !value.skills.is_empty(), + mcp_server_names: value.mcp_server_names, + app_connector_ids: value.apps, + } + } +} + #[derive(Debug, Clone, Default, PartialEq, Eq)] pub struct RemotePluginSyncResult { /// Plugin ids newly installed into the local plugin cache.