fix(omo): preserve custom fields and align otherFields import/validation

This commit is contained in:
YoVinchen
2026-02-12 01:14:30 +08:00
parent a301a81f7a
commit 651496eabb
6 changed files with 312 additions and 35 deletions
+70 -3
View File
@@ -286,6 +286,18 @@ impl OmoService {
let obj = Self::read_jsonc_object(&actual_path)?;
Ok(Self::build_local_file_data_from_obj(
&obj,
actual_path.to_string_lossy().to_string(),
last_modified,
))
}
fn build_local_file_data_from_obj(
obj: &Map<String, Value>,
file_path: String,
last_modified: Option<String>,
) -> OmoLocalFileData {
let agents = obj.get("agents").cloned();
let categories = obj.get("categories").cloned();
@@ -298,15 +310,16 @@ impl OmoService {
let mut global = OmoGlobalConfig::default();
Self::merge_global_from_obj(&obj, &mut global);
global.other_fields = other_fields.clone();
Ok(OmoLocalFileData {
OmoLocalFileData {
agents,
categories,
other_fields,
global,
file_path: actual_path.to_string_lossy().to_string(),
file_path,
last_modified,
})
}
}
fn strip_jsonc_comments(input: &str) -> String {
@@ -434,4 +447,58 @@ mod tests {
assert!(!obj.contains_key("disabled_agents"));
assert!(obj.contains_key("agents"));
}
#[test]
fn test_build_local_file_data_keeps_unknown_top_level_fields_in_global() {
let obj = serde_json::json!({
"$schema": "https://example.com/schema.json",
"disabled_agents": ["oracle"],
"agents": {
"sisyphus": { "model": "claude-opus-4-6" }
},
"categories": {
"code": { "model": "gpt-5.3" }
},
"custom_top_level": {
"enabled": true
}
});
let obj_map = obj.as_object().unwrap().clone();
let data = OmoService::build_local_file_data_from_obj(
&obj_map,
"/tmp/oh-my-opencode.jsonc".to_string(),
None,
);
assert_eq!(data.global.schema_url.as_deref(), Some("https://example.com/schema.json"));
assert_eq!(data.global.disabled_agents, vec!["oracle".to_string()]);
assert_eq!(
data.other_fields,
Some(serde_json::json!({
"custom_top_level": { "enabled": true }
}))
);
assert_eq!(data.global.other_fields, data.other_fields);
}
#[test]
fn test_merge_config_ignores_non_object_other_fields() {
let global = OmoGlobalConfig {
other_fields: Some(serde_json::json!(["global_non_object"])),
..Default::default()
};
let agents = None;
let categories = None;
let other_fields = Some(serde_json::json!("profile_non_object"));
let profile_data = (agents, categories, other_fields, true);
let merged = OmoService::merge_config(&global, Some(&profile_data));
let obj = merged.as_object().unwrap();
assert!(!obj.contains_key("0"));
assert!(!obj.contains_key("global_non_object"));
assert!(!obj.contains_key("profile_non_object"));
}
}