fix(codex): respect user-owned model_catalog_json when generating catalog (#6087)

The Some arm of set_codex_model_catalog_json_field unconditionally overwrote model_catalog_json with the cc-switch-owned filename, discarding any user-provided custom catalog path or filename. This mirrors the ownership check already present in the None arm: only claim the pointer when it is absent or already cc-switch-owned, leaving user-managed external catalog files untouched.

Add tests covering both full-path and relative-filename user-owned catalogs in the Some arm.
This commit is contained in:
misaka_myu authored and GitHub committed 2026-08-06 16:19:04 +08:00
1 parent 43eaf07355
commit 413c09e079
1 file changed
+54 -1
+54 -1
View File
@@ -1248,7 +1248,22 @@ fn set_codex_model_catalog_json_field(
match catalog_path {
Some(_) => {
doc["model_catalog_json"] = toml_edit::value(CC_SWITCH_CODEX_MODEL_CATALOG_FILENAME);
// Only claim the pointer when it is absent or already cc-switch-owned.
// A user-managed external catalog file (custom filename or path) is
// left untouched, mirroring the None arm's ownership rule that
// `resolve_cc_switch_catalog_path` relies on.
let is_cc_switch_owned = doc
.get("model_catalog_json")
.and_then(|item| item.as_str())
.map(|path| {
Path::new(path).file_name().and_then(|name| name.to_str())
== Some(CC_SWITCH_CODEX_MODEL_CATALOG_FILENAME)
})
.unwrap_or(true);
if is_cc_switch_owned {
doc["model_catalog_json"] =
toml_edit::value(CC_SWITCH_CODEX_MODEL_CATALOG_FILENAME);
}
}
None => {
let should_remove = doc
@@ -4296,6 +4311,44 @@ model = "glm-5"
);
}
#[test]
fn set_catalog_json_some_preserves_user_owned_catalog() {
// When CC Switch generates a catalog (Some arm), it must still respect a
// user-managed external catalog file instead of clobbering it with the
// cc-switch-owned filename. Only an absent or cc-switch-owned pointer is
// claimed; this mirrors the None arm's ownership rule.
let input = r#"model_provider = "custom"
model = "glm-5"
model_catalog_json = "/Users/me/.codex/my-custom-catalog.json"
"#;
let catalog_path = Path::new("/tmp/cc-switch-model-catalog.json");
let result = set_codex_model_catalog_json_field(input, Some(catalog_path)).unwrap();
let parsed: toml::Value = toml::from_str(&result).unwrap();
assert_eq!(
parsed.get("model_catalog_json").and_then(|v| v.as_str()),
Some("/Users/me/.codex/my-custom-catalog.json"),
"Some arm should NOT clobber a user-owned catalog (full path)"
);
}
#[test]
fn set_catalog_json_some_preserves_user_owned_relative_filename() {
// A bare custom filename (no directory component) is also user-owned
// and must be preserved by the Some arm.
let input = r#"model_provider = "custom"
model = "glm-5"
model_catalog_json = "my-custom-catalog.json"
"#;
let catalog_path = Path::new("/tmp/cc-switch-model-catalog.json");
let result = set_codex_model_catalog_json_field(input, Some(catalog_path)).unwrap();
let parsed: toml::Value = toml::from_str(&result).unwrap();
assert_eq!(
parsed.get("model_catalog_json").and_then(|v| v.as_str()),
Some("my-custom-catalog.json"),
"Some arm should NOT clobber a relative user-owned catalog"
);
}
#[test]
fn resolve_catalog_finds_relative_filename() {
let config_text = r#"model_provider = "custom"