This commit is contained in:
Ahmed Ibrahim
2026-03-25 01:46:26 -07:00
parent af4c07b59e
commit 83bd182dbd
4 changed files with 34 additions and 25 deletions
@@ -5504,7 +5504,7 @@ impl CodexMessageProcessor {
}
};
let config_layer_stack = match load_config_layers_state(
&self.codex_home,
&self.config.codex_home,
Some(cwd_abs),
cli_overrides,
LoaderOverrides::default(),
@@ -5529,14 +5529,14 @@ impl CodexMessageProcessor {
&config_layer_stack,
config.features.enabled(Feature::Plugins),
);
let skills_input = codex_core::skills::SkillsLoadInput::new(
cwd.clone(),
effective_skill_roots,
config_layer_stack,
config.bundled_skills_enabled(),
);
let outcome = skills_manager
.skills_for_cwd_with_extra_user_roots(
&cwd,
&effective_skill_roots,
force_reload,
extra_roots,
&config_layer_stack,
)
.skills_for_cwd_with_extra_user_roots(&skills_input, force_reload, extra_roots)
.await;
let errors = errors_to_info(&outcome.errors);
let skills = skills_to_info(&outcome.skills, &outcome.disabled_paths);
+6 -1
View File
@@ -264,6 +264,8 @@ fn config_write_error(code: ConfigWriteErrorCode, message: impl Into<String>) ->
mod tests {
use super::*;
use codex_core::AnalyticsEventsClient;
use codex_core::AuthManager;
use codex_core::CodexAuth;
use codex_core::config_loader::NetworkRequirementsToml as CoreNetworkRequirementsToml;
use codex_protocol::protocol::AskForApproval as CoreAskForApproval;
use pretty_assertions::assert_eq;
@@ -404,6 +406,9 @@ mod tests {
.await
.expect("load analytics config"),
);
let auth_manager = Arc::new(AuthManager::from_auth_for_testing(CodexAuth::from_api_key(
"test",
)));
let config_api = ConfigApi::new(
codex_home.path().to_path_buf(),
Vec::new(),
@@ -411,7 +416,7 @@ mod tests {
Arc::new(RwLock::new(CloudRequirementsLoader::default())),
reloader.clone(),
AnalyticsEventsClient::new(
Arc::clone(&analytics_config.auth_manager),
auth_manager,
analytics_config
.chatgpt_base_url
.trim_end_matches('/')
@@ -1,6 +1,7 @@
use super::*;
use codex_protocol::items::HookPromptFragment;
use codex_protocol::items::build_hook_prompt_message;
use codex_protocol::models::ResponseItem;
#[test]
fn detects_environment_context_fragment() {
+19 -16
View File
@@ -15,6 +15,7 @@ use crate::plugins::test_support::write_curated_plugin_sha_with as write_curated
use crate::plugins::test_support::write_file;
use crate::plugins::test_support::write_openai_curated_marketplace;
use codex_app_server_protocol::ConfigLayerSource;
use codex_plugin::prompt_safe_plugin_description;
use codex_protocol::protocol::Product;
use pretty_assertions::assert_eq;
use std::fs;
@@ -28,6 +29,8 @@ use wiremock::matchers::method;
use wiremock::matchers::path;
use wiremock::matchers::query_param;
const MAX_CAPABILITY_SUMMARY_DESCRIPTION_LEN: usize = 1024;
fn write_plugin(root: &Path, dir_name: &str, manifest_name: &str) {
let plugin_root = root.join(dir_name);
fs::create_dir_all(plugin_root.join(".codex-plugin")).unwrap();
@@ -132,7 +135,7 @@ fn load_plugins_loads_default_skills_and_mcp_servers() {
let outcome = load_plugins_from_config(&plugin_config_toml(true, true), codex_home.path());
assert_eq!(
outcome.plugins,
outcome.plugins(),
vec![LoadedPlugin {
config_name: "sample@test".to_string(),
manifest_name: Some("sample".to_string()),
@@ -222,10 +225,10 @@ enabled = true
let skill_path = dunce::canonicalize(skill_path).expect("skill path should canonicalize");
assert_eq!(
outcome.plugins[0].disabled_skill_paths,
outcome.plugins()[0].disabled_skill_paths,
HashSet::from([skill_path])
);
assert!(!outcome.plugins[0].has_enabled_skills);
assert!(!outcome.plugins()[0].has_enabled_skills);
assert!(outcome.capability_summaries().is_empty());
}
@@ -258,8 +261,8 @@ enabled = true
"#;
let outcome = load_plugins_from_config(config_toml, codex_home.path());
assert!(outcome.plugins[0].disabled_skill_paths.is_empty());
assert!(outcome.plugins[0].has_enabled_skills);
assert!(outcome.plugins()[0].disabled_skill_paths.is_empty());
assert!(outcome.plugins()[0].has_enabled_skills);
assert_eq!(
outcome.capability_summaries(),
&[PluginCapabilitySummary {
@@ -340,7 +343,7 @@ fn capability_summary_sanitizes_plugin_descriptions_to_one_line() {
let outcome = load_plugins_from_config(&plugin_config_toml(true, true), codex_home.path());
assert_eq!(
outcome.plugins[0].manifest_description.as_deref(),
outcome.plugins()[0].manifest_description.as_deref(),
Some("Plugin that\n includes the sample\tserver")
);
assert_eq!(
@@ -375,7 +378,7 @@ fn capability_summary_truncates_overlong_plugin_descriptions() {
let outcome = load_plugins_from_config(&plugin_config_toml(true, true), codex_home.path());
assert_eq!(
outcome.plugins[0].manifest_description.as_deref(),
outcome.plugins()[0].manifest_description.as_deref(),
Some(too_long.as_str())
);
assert_eq!(
@@ -455,14 +458,14 @@ fn load_plugins_uses_manifest_configured_component_paths() {
let outcome = load_plugins_from_config(&plugin_config_toml(true, true), codex_home.path());
assert_eq!(
outcome.plugins[0].skill_roots,
outcome.plugins()[0].skill_roots,
vec![
plugin_root.join("custom-skills"),
plugin_root.join("skills")
]
);
assert_eq!(
outcome.plugins[0].mcp_servers,
outcome.plugins()[0].mcp_servers,
HashMap::from([(
"custom".to_string(),
McpServerConfig {
@@ -485,7 +488,7 @@ fn load_plugins_uses_manifest_configured_component_paths() {
)])
);
assert_eq!(
outcome.plugins[0].apps,
outcome.plugins()[0].apps,
vec![AppConnectorId("connector_custom".to_string())]
);
}
@@ -561,11 +564,11 @@ fn load_plugins_ignores_manifest_component_paths_without_dot_slash() {
let outcome = load_plugins_from_config(&plugin_config_toml(true, true), codex_home.path());
assert_eq!(
outcome.plugins[0].skill_roots,
outcome.plugins()[0].skill_roots,
vec![plugin_root.join("skills")]
);
assert_eq!(
outcome.plugins[0].mcp_servers,
outcome.plugins()[0].mcp_servers,
HashMap::from([(
"default".to_string(),
McpServerConfig {
@@ -588,7 +591,7 @@ fn load_plugins_ignores_manifest_component_paths_without_dot_slash() {
)])
);
assert_eq!(
outcome.plugins[0].apps,
outcome.plugins()[0].apps,
vec![AppConnectorId("connector_default".to_string())]
);
}
@@ -620,7 +623,7 @@ fn load_plugins_preserves_disabled_plugins_without_effective_contributions() {
let outcome = load_plugins_from_config(&plugin_config_toml(false, true), codex_home.path());
assert_eq!(
outcome.plugins,
outcome.plugins(),
vec![LoadedPlugin {
config_name: "sample@test".to_string(),
manifest_name: None,
@@ -864,9 +867,9 @@ fn load_plugins_rejects_invalid_plugin_keys() {
codex_home.path(),
);
assert_eq!(outcome.plugins.len(), 1);
assert_eq!(outcome.plugins().len(), 1);
assert_eq!(
outcome.plugins[0].error.as_deref(),
outcome.plugins()[0].error.as_deref(),
Some("invalid plugin key `sample`; expected <plugin>@<marketplace>")
);
assert!(outcome.effective_skill_roots().is_empty());