use std::fs;
use std::path::PathBuf;
use crate::error::{Error, IoContext, Result};
use crate::host::{Plugin, data_root};
const FLAG: &str = "restart-pending";
fn path(plugin: &Plugin) -> Result<PathBuf> {
Ok(data_root(plugin)?.join(FLAG))
}
pub(crate) fn set(plugin: &Plugin) -> Result<()> {
let path = path(plugin)?;
if let Some(parent) = path.parent() {
fs::create_dir_all(parent).io_ctx(|| format!("creating {}", parent.display()))?;
}
fs::write(&path, []).io_ctx(|| format!("writing {}", path.display()))
}
pub(crate) fn clear(plugin: &Plugin) -> Result<()> {
match fs::remove_file(path(plugin)?) {
Ok(()) => Ok(()),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()),
Err(source) => Err(Error::Io { context: "clearing restart-pending".into(), source }),
}
}
pub(crate) fn pending(plugin: &Plugin) -> Result<Option<()>> {
match fs::metadata(path(plugin)?) {
Ok(_) => Ok(Some(())),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(None),
Err(source) => Err(Error::Io { context: "reading restart-pending".into(), source }),
}
}
pub(crate) fn message(name: &str, version: &str) -> String {
format!(
"The `{name}` Claude Code plugin was updated to {version} after this session started. \
This session still has the previous version loaded; the updated hooks, commands, and \
agents take effect after a `/reload-plugins`, or a full Claude Code restart."
)
}
#[cfg(test)]
#[path = "../tests/unit/restart.rs"]
mod restart_tests;