use anyhow::Result;
use oxicode_catalog::oxi_home;
use std::path::PathBuf;
use super::reset::display_path;
fn journal_status(journal_path: Option<PathBuf>) -> String {
let Some(path) = journal_path.filter(|p| p.exists()) else {
return "absent".to_string();
};
match crate::home_migrate::MigrationJournal::load(&path) {
Some(j) if j.is_in_progress() => "in_progress".to_string(),
Some(j) if j.status == "complete" => "complete".to_string(),
Some(_) => "present (unexpected status)".to_string(),
None => "present (unreadable)".to_string(),
}
}
pub fn handle_doctor() -> Result<()> {
println!("Oxi home layout");
println!("---------------");
let oxi = oxi_home::oxi_home();
let canonical = oxi_home::oxicode_home();
let legacy = oxi_home::legacy_home_dir();
let journal_path = oxi_home::migration_journal_path();
println!(
" oxi home: {}",
oxi.as_ref()
.map(|p| display_path(p))
.unwrap_or_else(|| "<unresolvable>".to_string())
);
println!(
" oxicode home: {} (canonical, owned by oxicode)",
canonical
.as_ref()
.map(|p| display_path(p))
.unwrap_or_else(|| "<unresolvable>".to_string())
);
if let Some(env_val) = std::env::var_os("OXICODE_HOME") {
println!(
" override: OXICODE_HOME={}",
env_val.to_string_lossy()
);
} else if let Some(env_val) = std::env::var_os("OXI_HOME") {
println!(" override: OXI_HOME={}", env_val.to_string_lossy());
}
match &legacy {
Some(legacy_dir) => {
println!(
" legacy home: {} (present, read-only)",
display_path(legacy_dir)
);
let complete = journal_status(journal_path.clone()) == "complete";
if canonical.as_ref().is_some_and(|c| c.exists()) && complete {
println!(" migration: complete");
} else {
println!(" migration: pending (run `oxicode migrate home`)");
}
}
None => {
println!(" legacy home: absent");
println!(" migration: nothing to do");
}
}
println!(
" journal: {}",
journal_status(journal_path).replace(
"in_progress",
"in_progress (rerun `oxicode migrate home` to resume)"
)
);
if let Some(home) = canonical {
println!();
println!("Owned paths");
println!("-----------");
for (label, rel) in [
("settings", "settings.json"),
("auth", "auth.json"),
("sessions", "sessions"),
("skills", "skills"),
("extensions", "extensions"),
("packages", "packages"),
("catalog overrides", "catalog/overrides.toml"),
("models.dev cache", "cache/models-dev.json"),
] {
println!(
" {:<18} {}",
format!("{label}:"),
display_path(&home.join(rel))
);
}
}
if let Ok(cwd) = std::env::current_dir() {
let project = cwd.join(".oxicode");
if project.is_dir() {
println!();
println!(
" note: project-local .oxicode/ found at {} (separate namespace, not migrated)",
display_path(&project)
);
}
}
Ok(())
}