use std::path::PathBuf;
use crate::error::RecallError;
pub fn entity_root() -> Result<PathBuf, RecallError> {
if let Ok(p) = std::env::var("RECALL_ECHO_HOME") {
return Ok(PathBuf::from(p));
}
std::env::current_dir().map_err(RecallError::from)
}
pub fn memory_dir() -> Result<PathBuf, RecallError> {
Ok(entity_root()?.join("memory"))
}
pub fn memory_file() -> Result<PathBuf, RecallError> {
Ok(memory_dir()?.join("MEMORY.md"))
}
pub fn ephemeral_file() -> Result<PathBuf, RecallError> {
Ok(memory_dir()?.join("EPHEMERAL.md"))
}
pub fn archive_index() -> Result<PathBuf, RecallError> {
Ok(memory_dir()?.join("ARCHIVE.md"))
}
pub fn conversations_dir() -> Result<PathBuf, RecallError> {
Ok(memory_dir()?.join("conversations"))
}
pub fn config_file() -> Result<PathBuf, RecallError> {
Ok(memory_dir()?.join(".recall-echo.toml"))
}
pub fn claude_dir() -> Result<PathBuf, RecallError> {
let home = dirs::home_dir()
.ok_or_else(|| RecallError::Other("Could not determine home directory".into()))?;
Ok(home.join(".claude"))
}
#[must_use]
pub fn expand_tilde(path: &str) -> String {
if let Some(rest) = path.strip_prefix("~/") {
if let Some(home) = dirs::home_dir() {
return home.join(rest).to_string_lossy().to_string();
}
}
path.to_string()
}
#[must_use]
pub fn detect_claude_code() -> Option<PathBuf> {
let home = dirs::home_dir()?;
let claude = home.join(".claude");
if claude.exists() {
Some(claude)
} else {
None
}
}