use crate::config::external_agent_config::ExternalAgentConfigDetectOptions; use crate::config::external_agent_config::ExternalAgentConfigMigrationItem as CoreMigrationItem; use crate::config::external_agent_config::ExternalAgentConfigMigrationItemType as CoreMigrationItemType; use crate::config::external_agent_config::ExternalAgentConfigService; use crate::config::external_agent_config::PendingPluginImport; use crate::error_code::internal_error; use codex_app_server_protocol::ExternalAgentConfigDetectParams; use codex_app_server_protocol::ExternalAgentConfigDetectResponse; use codex_app_server_protocol::ExternalAgentConfigImportParams; use codex_app_server_protocol::ExternalAgentConfigMigrationItem; use codex_app_server_protocol::ExternalAgentConfigMigrationItemType; use codex_app_server_protocol::JSONRPCErrorError; use codex_app_server_protocol::MigrationDetails; use codex_app_server_protocol::PluginsMigration; use std::path::PathBuf; #[derive(Clone)] pub(crate) struct ExternalAgentConfigApi { migration_service: ExternalAgentConfigService, } impl ExternalAgentConfigApi { pub(crate) fn new(codex_home: PathBuf) -> Self { Self { migration_service: ExternalAgentConfigService::new(codex_home), } } pub(crate) async fn detect( &self, params: ExternalAgentConfigDetectParams, ) -> Result { let items = self .migration_service .detect(ExternalAgentConfigDetectOptions { include_home: params.include_home, cwds: params.cwds, }) .await .map_err(|err| internal_error(err.to_string()))?; Ok(ExternalAgentConfigDetectResponse { items: items .into_iter() .map(|migration_item| ExternalAgentConfigMigrationItem { item_type: match migration_item.item_type { CoreMigrationItemType::Config => { ExternalAgentConfigMigrationItemType::Config } CoreMigrationItemType::Skills => { ExternalAgentConfigMigrationItemType::Skills } CoreMigrationItemType::AgentsMd => { ExternalAgentConfigMigrationItemType::AgentsMd } CoreMigrationItemType::Plugins => { ExternalAgentConfigMigrationItemType::Plugins } CoreMigrationItemType::McpServerConfig => { ExternalAgentConfigMigrationItemType::McpServerConfig } }, description: migration_item.description, cwd: migration_item.cwd, details: migration_item.details.map(|details| MigrationDetails { plugins: details .plugins .into_iter() .map(|plugin| PluginsMigration { marketplace_name: plugin.marketplace_name, plugin_names: plugin.plugin_names, }) .collect(), }), }) .collect(), }) } pub(crate) async fn import( &self, params: ExternalAgentConfigImportParams, ) -> Result, JSONRPCErrorError> { self.migration_service .import( params .migration_items .into_iter() .map(|migration_item| CoreMigrationItem { item_type: match migration_item.item_type { ExternalAgentConfigMigrationItemType::Config => { CoreMigrationItemType::Config } ExternalAgentConfigMigrationItemType::Skills => { CoreMigrationItemType::Skills } ExternalAgentConfigMigrationItemType::AgentsMd => { CoreMigrationItemType::AgentsMd } ExternalAgentConfigMigrationItemType::Plugins => { CoreMigrationItemType::Plugins } ExternalAgentConfigMigrationItemType::McpServerConfig => { CoreMigrationItemType::McpServerConfig } }, description: migration_item.description, cwd: migration_item.cwd, details: migration_item.details.map(|details| { crate::config::external_agent_config::MigrationDetails { plugins: details .plugins .into_iter() .map(|plugin| { crate::config::external_agent_config::PluginsMigration { marketplace_name: plugin.marketplace_name, plugin_names: plugin.plugin_names, } }) .collect(), } }), }) .collect(), ) .await .map_err(|err| internal_error(err.to_string())) } pub(crate) async fn complete_pending_plugin_import( &self, pending_plugin_import: PendingPluginImport, ) -> Result<(), JSONRPCErrorError> { self.migration_service .import_plugins( pending_plugin_import.cwd.as_deref(), Some(pending_plugin_import.details), ) .await .map(|_| ()) .map_err(|err| internal_error(err.to_string())) } }