use crate::holder::{Holder, Location, Noun, Remedy};
pub(crate) const HOLDERS: &[Holder] = &[
Holder {
kind: "chatgpt_app",
noun: Noun::One("the ChatGPT app"),
location: Location::Within("ChatGPT.app"),
remedy: Remedy::ReopenApp {
bundle_id: "com.openai.codex",
name: "ChatGPT",
},
},
Holder {
kind: "app_server_daemon",
noun: Noun::One("Codex's background app server"),
location: Location::Within("app-server-daemon"),
remedy: Remedy::Run("codex app-server daemon restart"),
},
Holder {
kind: "editor_extension",
noun: Noun::One("Codex in an editor"),
location: Location::WithinPrefixed("openai.chatgpt-"),
remedy: Remedy::Do("run Developer: Reload Window in each editor window that uses it"),
},
Holder {
kind: "session",
noun: Noun::Counted {
one: "`codex` session",
many: "`codex` sessions",
},
location: Location::Anywhere,
remedy: Remedy::Restart,
},
];
#[cfg(test)]
mod tests {
use super::*;
use crate::holder::classify;
use crate::process::Process;
use std::path::PathBuf;
#[test]
fn every_measured_codex_is_its_own_kind() {
let listed = [
"codex",
"/Users/a/.codex/packages/standalone/releases/0.154.0-aarch64-apple-darwin/bin/codex",
"/Applications/ChatGPT.app/Contents/Resources/codex-cli/CodexCLI.app/Contents/MacOS/codex",
"/Applications/ChatGPT.app/Contents/Resources/codex-cli/CodexCLI.app/Contents/MacOS/codex",
"/Users/a/.codex/packages/app-server-daemon/releases/0.159.3-aarch64-apple-darwin/bin/codex",
"/Users/a/.vscode/extensions/openai.chatgpt-26.5.0-darwin-arm64/bin/macos-aarch64/codex",
];
let processes: Vec<Process> = (1..)
.zip(listed)
.map(|(pid, path)| Process {
pid,
path: PathBuf::from(path),
})
.collect();
let holding = classify(&processes, HOLDERS);
let kinds: Vec<(&str, Vec<u32>)> = holding
.iter()
.map(|h| (h.holder.kind, h.pids.clone()))
.collect();
assert_eq!(
kinds,
[
("chatgpt_app", vec![3, 4]),
("app_server_daemon", vec![5]),
("editor_extension", vec![6]),
("session", vec![1, 2]),
]
);
}
#[test]
fn the_last_kind_is_anywhere() {
assert_eq!(HOLDERS.last().map(|h| h.location), Some(Location::Anywhere));
assert!(
HOLDERS[..HOLDERS.len() - 1]
.iter()
.all(|h| h.location != Location::Anywhere),
"and nothing before it claims everything"
);
}
}