Skip to content

Commit 0732034

Browse files
committed
fix: migrate persisted open app targets to include PHPStorm
1 parent 3f18662 commit 0732034

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

src-tauri/src/storage.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ pub(crate) fn read_settings(path: &PathBuf) -> Result<AppSettings, String> {
3131
let data = std::fs::read_to_string(path).map_err(|e| e.to_string())?;
3232
let mut value: Value = serde_json::from_str(&data).map_err(|e| e.to_string())?;
3333
migrate_follow_up_message_behavior(&mut value);
34+
migrate_open_app_targets(&mut value);
3435
match serde_json::from_value(value.clone()) {
3536
Ok(settings) => Ok(settings),
3637
Err(_) => {
3738
sanitize_remote_settings_for_tcp_only(&mut value);
3839
migrate_follow_up_message_behavior(&mut value);
40+
migrate_open_app_targets(&mut value);
3941
serde_json::from_value(value).map_err(|e| e.to_string())
4042
}
4143
}
@@ -92,6 +94,47 @@ fn migrate_follow_up_message_behavior(value: &mut Value) {
9294
);
9395
}
9496

97+
fn migrate_open_app_targets(value: &mut Value) {
98+
let Value::Object(root) = value else {
99+
return;
100+
};
101+
let Some(Value::Array(existing_targets)) = root.get_mut("openAppTargets") else {
102+
return;
103+
};
104+
105+
let default_targets = match serde_json::to_value(AppSettings::default().open_app_targets) {
106+
Ok(Value::Array(targets)) => targets,
107+
_ => return,
108+
};
109+
110+
let existing_ids = existing_targets
111+
.iter()
112+
.filter_map(|target| target.get("id").and_then(Value::as_str))
113+
.collect::<std::collections::HashSet<_>>();
114+
115+
let missing_targets: Vec<Value> = default_targets
116+
.into_iter()
117+
.filter(|target| {
118+
target
119+
.get("id")
120+
.and_then(Value::as_str)
121+
.map(|id| !existing_ids.contains(id))
122+
.unwrap_or(false)
123+
})
124+
.collect();
125+
126+
if missing_targets.is_empty() {
127+
return;
128+
}
129+
130+
let insert_at = existing_targets
131+
.iter()
132+
.position(|target| target.get("id").and_then(Value::as_str) == Some("finder"))
133+
.unwrap_or(existing_targets.len());
134+
135+
existing_targets.splice(insert_at..insert_at, missing_targets);
136+
}
137+
95138
#[cfg(test)]
96139
mod tests {
97140
use super::{read_settings, read_workspaces, write_workspaces};
@@ -251,4 +294,48 @@ mod tests {
251294
let settings = read_settings(&path).expect("read settings");
252295
assert_eq!(settings.follow_up_message_behavior, "queue");
253296
}
297+
298+
#[test]
299+
fn read_settings_migrates_missing_open_app_targets() {
300+
let temp_dir = std::env::temp_dir().join(format!("codex-monitor-test-{}", Uuid::new_v4()));
301+
std::fs::create_dir_all(&temp_dir).expect("create temp dir");
302+
let path = temp_dir.join("settings.json");
303+
304+
std::fs::write(
305+
&path,
306+
r#"{
307+
"theme": "dark",
308+
"selectedOpenAppId": "vscode",
309+
"openAppTargets": [
310+
{ "id": "vscode", "label": "VS Code", "kind": "command", "appName": null, "command": "code", "args": [] },
311+
{ "id": "cursor", "label": "Cursor", "kind": "command", "appName": null, "command": "cursor", "args": [] },
312+
{ "id": "zed", "label": "Zed", "kind": "command", "appName": null, "command": "zed", "args": [] },
313+
{ "id": "ghostty", "label": "Ghostty", "kind": "command", "appName": null, "command": "ghostty", "args": [] },
314+
{ "id": "antigravity", "label": "Antigravity", "kind": "command", "appName": null, "command": "antigravity", "args": [] },
315+
{ "id": "finder", "label": "File Manager", "kind": "finder", "appName": null, "command": null, "args": [] }
316+
]
317+
}"#,
318+
)
319+
.expect("write settings");
320+
321+
let settings = read_settings(&path).expect("read settings");
322+
let ids: Vec<&str> = settings
323+
.open_app_targets
324+
.iter()
325+
.map(|target| target.id.as_str())
326+
.collect();
327+
328+
assert_eq!(
329+
ids,
330+
vec![
331+
"vscode",
332+
"cursor",
333+
"zed",
334+
"ghostty",
335+
"antigravity",
336+
"phpstorm",
337+
"finder"
338+
]
339+
);
340+
}
254341
}

0 commit comments

Comments
 (0)