respect workspace option for disabling plugins (#18907)

Respects the workspace setting for plugins in Codex

Plugins menu disappears
Plugins do not load
Plugins do not load in composer

no plugins loaded
<img width="809" height="226" alt="Screenshot 2026-04-23 at 3 20 45 PM"
src="https://github.com/user-attachments/assets/3a4dba8e-69c3-4046-a77e-f13ab77f84b4"
/>


no plugins in menu
<img width="293" height="204" alt="Screenshot 2026-04-23 at 3 20 35 PM"
src="https://github.com/user-attachments/assets/5cb9bf52-ad72-488f-b90c-5eb457da09a3"
/>
This commit is contained in:
Alex Zamoshchin
2026-04-24 13:38:45 -04:00
committed by GitHub
Unverified
parent f802f0a391
commit bcc1caa920
11 changed files with 851 additions and 7 deletions
@@ -219,6 +219,7 @@ use codex_arg0::Arg0DispatchPaths;
use codex_backend_client::AddCreditsNudgeCreditType as BackendAddCreditsNudgeCreditType;
use codex_backend_client::Client as BackendClient;
use codex_chatgpt::connectors;
use codex_chatgpt::workspace_settings;
use codex_config::types::McpServerTransportConfig;
use codex_core::CodexThread;
use codex_core::CodexThreadTurnContextOverrides;
@@ -498,6 +499,7 @@ pub(crate) struct CodexMessageProcessor {
thread_state_manager: ThreadStateManager,
thread_watch_manager: ThreadWatchManager,
command_exec_manager: CommandExecManager,
workspace_settings_cache: Arc<workspace_settings::WorkspaceSettingsCache>,
pending_fuzzy_searches: Arc<Mutex<HashMap<String, Arc<AtomicBool>>>>,
fuzzy_search_sessions: Arc<Mutex<HashMap<String, FuzzyFileSearchSession>>>,
background_tasks: TaskTracker,
@@ -762,6 +764,9 @@ impl CodexMessageProcessor {
thread_state_manager: ThreadStateManager::new(),
thread_watch_manager: ThreadWatchManager::new_with_outgoing(outgoing),
command_exec_manager: CommandExecManager::default(),
workspace_settings_cache: Arc::new(
workspace_settings::WorkspaceSettingsCache::default(),
),
pending_fuzzy_searches: Arc::new(Mutex::new(HashMap::new())),
fuzzy_search_sessions: Arc::new(Mutex::new(HashMap::new())),
background_tasks: TaskTracker::new(),
@@ -784,6 +789,28 @@ impl CodexMessageProcessor {
})
}
async fn workspace_codex_plugins_enabled(
&self,
config: &Config,
auth: Option<&CodexAuth>,
) -> bool {
match workspace_settings::codex_plugins_enabled_for_workspace(
config,
auth,
Some(&self.workspace_settings_cache),
)
.await
{
Ok(enabled) => enabled,
Err(err) => {
warn!(
"failed to fetch workspace Codex plugins setting; allowing Codex plugins: {err:#}"
);
true
}
}
}
/// If a client sends `developer_instructions: null` during a mode switch,
/// use the built-in instructions for that mode.
fn normalize_turn_start_collaboration_mode(
@@ -5608,6 +5635,10 @@ impl CodexMessageProcessor {
return;
}
};
let auth = self.auth_manager.auth().await;
let workspace_codex_plugins_enabled = self
.workspace_codex_plugins_enabled(&config, auth.as_ref())
.await;
let data = FEATURES
.iter()
@@ -5642,7 +5673,9 @@ impl CodexMessageProcessor {
display_name,
description,
announcement,
enabled: config.features.enabled(spec.id),
enabled: config.features.enabled(spec.id)
&& (workspace_codex_plugins_enabled
|| !matches!(spec.id, Feature::Apps | Feature::Plugins)),
default_enabled: spec.default_enabled,
}
})
@@ -6430,6 +6463,22 @@ impl CodexMessageProcessor {
return;
}
if !self
.workspace_codex_plugins_enabled(&config, auth.as_ref())
.await
{
self.outgoing
.send_response(
request_id,
AppsListResponse {
data: Vec::new(),
next_cursor: None,
},
)
.await;
return;
}
let request = request_id.clone();
let outgoing = Arc::clone(&self.outgoing);
let environment_manager = self.thread_manager.environment_manager();
@@ -6674,6 +6723,10 @@ impl CodexMessageProcessor {
return;
}
};
let auth = self.auth_manager.auth().await;
let workspace_codex_plugins_enabled = self
.workspace_codex_plugins_enabled(&config, auth.as_ref())
.await;
let skills_manager = self.thread_manager.skills_manager();
let plugins_manager = self.thread_manager.plugins_manager();
let fs = self
@@ -6723,7 +6776,7 @@ impl CodexMessageProcessor {
let effective_skill_roots = plugins_manager
.effective_skill_roots_for_layer_stack(
&config_layer_stack,
config.features.enabled(Feature::Plugins),
config.features.enabled(Feature::Plugins) && workspace_codex_plugins_enabled,
)
.await;
let skills_input = codex_core::skills::SkillsLoadInput::new(