mirror of
https://github.com/openai/codex.git
synced 2026-10-26 18:38:47 +00:00
[codex] Ignore local curated plugins when remote catalog is active (#29765)
## Summary - suppress configured `openai-curated` plugins when the remote plugin feature is enabled and auth uses the Codex backend - preserve `openai-api-curated` and non-Codex-backend behavior while including remote catalog activation in the plugin load cache key - add core plugin coverage and an app-server integration test for runtime feature enablement ## Why The Codex app enables remote plugins through process-local runtime feature enablement, which can happen after app-server startup tasks have already observed legacy local plugin state. The existing conflict logic only preferred a remote plugin when the same plugin was already installed remotely, so a configured legacy-only plugin could continue exposing skills and other capabilities from `openai-curated`. ## Impact When the remote catalog is active, legacy `openai-curated` plugins no longer contribute skills, MCP servers, apps, or hooks. Remote installed plugins continue to load normally, and `openai-api-curated` remains unaffected. This does not change remote fetch, bundle sync, or uninstall behavior. ## Validation - `just test -p codex-core-plugins remote_global_catalog_ignores_local_curated_plugins remote_plugin_feature_keeps_local_curated_without_codex_backend` - `just test -p codex-app-server runtime_remote_plugin_enablement_excludes_local_curated_plugin_skills` - `just fmt` - `git diff --check`
This commit is contained in:
@@ -384,15 +384,15 @@ struct LoadedPluginsCache {
|
||||
struct PluginLoadCacheKey {
|
||||
configured_plugins: HashMap<String, PluginConfig>,
|
||||
skill_config_rules: SkillConfigRules,
|
||||
remote_plugin_enabled: bool,
|
||||
remote_global_catalog_active: bool,
|
||||
}
|
||||
|
||||
impl PluginLoadCacheKey {
|
||||
fn from_config(config: &PluginsConfigInput) -> Self {
|
||||
fn from_config(config: &PluginsConfigInput, remote_global_catalog_active: bool) -> Self {
|
||||
Self {
|
||||
configured_plugins: configured_plugins_from_stack(&config.config_layer_stack),
|
||||
skill_config_rules: skill_config_rules_from_stack(&config.config_layer_stack),
|
||||
remote_plugin_enabled: config.remote_plugin_enabled,
|
||||
remote_global_catalog_active,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -459,6 +459,10 @@ impl PluginsManager {
|
||||
}
|
||||
}
|
||||
|
||||
fn remote_global_catalog_active(&self, config: &PluginsConfigInput) -> bool {
|
||||
config.remote_plugin_enabled && self.auth_mode().is_some_and(AuthMode::uses_codex_backend)
|
||||
}
|
||||
|
||||
pub fn set_analytics_events_client(&self, analytics_events_client: AnalyticsEventsClient) {
|
||||
let mut stored_client = match self.analytics_events_client.write() {
|
||||
Ok(client_guard) => client_guard,
|
||||
@@ -490,7 +494,8 @@ impl PluginsManager {
|
||||
if !config.plugins_enabled {
|
||||
return None;
|
||||
}
|
||||
let key = PluginLoadCacheKey::from_config(config);
|
||||
let key =
|
||||
PluginLoadCacheKey::from_config(config, self.remote_global_catalog_active(config));
|
||||
self.loaded_plugins_cache
|
||||
.read()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner)
|
||||
@@ -519,7 +524,8 @@ impl PluginsManager {
|
||||
return PluginLoadOutcome::default();
|
||||
}
|
||||
|
||||
let cache_key = PluginLoadCacheKey::from_config(config);
|
||||
let remote_global_catalog_active = self.remote_global_catalog_active(config);
|
||||
let cache_key = PluginLoadCacheKey::from_config(config, remote_global_catalog_active);
|
||||
if !force_reload && let Some(plugins) = self.cached_loaded_plugins(&cache_key) {
|
||||
return self.resolve_loaded_plugins_for_auth(plugins);
|
||||
}
|
||||
@@ -539,7 +545,7 @@ impl PluginsManager {
|
||||
&self.store,
|
||||
Some(&plugin_skill_snapshots),
|
||||
self.restriction_product,
|
||||
config.remote_plugin_enabled,
|
||||
remote_global_catalog_active,
|
||||
)
|
||||
.await;
|
||||
log_plugin_load_errors(&plugins);
|
||||
@@ -624,7 +630,7 @@ impl PluginsManager {
|
||||
&self.store,
|
||||
/*plugin_skill_snapshots*/ None,
|
||||
self.restriction_product,
|
||||
config.remote_plugin_enabled,
|
||||
self.remote_global_catalog_active(config),
|
||||
)
|
||||
.await;
|
||||
self.resolve_loaded_plugins_for_auth(plugins)
|
||||
@@ -643,7 +649,7 @@ impl PluginsManager {
|
||||
config_layer_stack,
|
||||
self.remote_installed_plugin_configs(),
|
||||
&self.store,
|
||||
config.remote_plugin_enabled,
|
||||
self.remote_global_catalog_active(config),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user