use std::path::{Path, PathBuf};
use lingshu_types::ToolError;
use crate::tools::backends::shell_quote;
pub(crate) const BACKEND_TMP_ROOT: &str = "/tmp/lingshu-tmp";
fn resolve_lingshu_home() -> PathBuf {
std::env::var("EDGECRAB_HOME")
.map(PathBuf::from)
.unwrap_or_else(|_| {
if cfg!(test) {
return std::env::temp_dir()
.join(format!("lingshu-test-home-{}", std::process::id()));
}
dirs::home_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join(".lingshu")
})
}
pub(crate) fn shared_tmp_dir(lingshu_home: &Path) -> PathBuf {
lingshu_home.join("tmp").join("files")
}
pub(crate) fn default_shared_tmp_dir() -> PathBuf {
shared_tmp_dir(&resolve_lingshu_home())
}
pub(crate) fn ensure_default_shared_tmp_dir() -> Result<PathBuf, ToolError> {
let dir = default_shared_tmp_dir();
std::fs::create_dir_all(&dir).map_err(|e| ToolError::ExecutionFailed {
tool: "terminal".into(),
message: format!(
"Failed to create Lingshu shared temp root '{}': {e}",
dir.display()
),
})?;
Ok(dir)
}
pub(crate) fn temp_env_pairs(tmp_root: &str) -> [(String, String); 4] {
[
("EDGECRAB_TMPDIR".into(), tmp_root.into()),
("TMPDIR".into(), tmp_root.into()),
("TMP".into(), tmp_root.into()),
("TEMP".into(), tmp_root.into()),
]
}
pub(crate) fn wrap_command_with_tmp_env(command: &str, tmp_root: &str) -> String {
let quoted = shell_quote(tmp_root);
format!(
"mkdir -p {quoted} && export EDGECRAB_TMPDIR={quoted} TMPDIR={quoted} TMP={quoted} TEMP={quoted} && {command}"
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn temp_env_pairs_populates_standard_keys() {
let vars = temp_env_pairs("/tmp/lingshu-tmp");
assert!(
vars.iter()
.any(|(k, v)| k == "TMPDIR" && v == "/tmp/lingshu-tmp")
);
assert!(
vars.iter()
.any(|(k, v)| k == "EDGECRAB_TMPDIR" && v == "/tmp/lingshu-tmp")
);
}
#[test]
fn wrap_command_with_tmp_env_exports_and_executes() {
let wrapped = wrap_command_with_tmp_env("python3 script.py", "/tmp/lingshu-tmp");
assert!(wrapped.contains("mkdir -p '/tmp/lingshu-tmp'"));
assert!(wrapped.contains("TMPDIR='/tmp/lingshu-tmp'"));
assert!(wrapped.ends_with("python3 script.py"));
}
}