fix: the server's own folders under a short-named temp path are expanded, not refused (#1055)

On Windows the temporary folder often has an 8.3 short name, which the path scope refuses. vfs::long_names spells folders SolidCraft derives from the environment with long names, and the MCP scratch folder and the recovery folder use it, so screenshot without a path and the recovery commands work there again.
This commit is contained in:
NOWN-DEV authored and GitHub committed 2026-10-14 09:05:43 -04:00
1 parent cf93869c4d
commit 08b6a8fe0f
10 files changed
+165 -16

No files matched your search

+1 -1
View File
@@ -130,7 +130,7 @@ fn motion_study_plays_and_exports() {
// The B occurrence's origin moves by the slider value (it starts at 0 offset with value 0 at 10 mm… so 10 → −5).
assert!((bx(&rows[1]) - bx(&rows[0]) + 3.75).abs() < 1e-6, "{e}");
assert!(rows[4]["stopped_by_contact"].is_object());
let dir = std::env::temp_dir().join(format!("solidcraft-motion-{}", std::process::id()));
let dir = solidcraft_io::vfs::temp_dir().join(format!("solidcraft-motion-{}", std::process::id()));
std::fs::create_dir_all(&dir).unwrap();
let csv = dir.join("push.csv");
run(&mut s, "motion.export", json!({"study": "Push", "samples": 3, "path": csv.to_string_lossy()}));
+1 -1
View File
@@ -96,7 +96,7 @@ fn assert_fk(m: &UrdfModel, s: &Session, what: &str) {
}
fn temp(tag: &str) -> PathBuf {
let d = std::env::temp_dir().join(format!("solidcraft-urdf-{tag}-{}", std::process::id()));
let d = solidcraft_io::vfs::temp_dir().join(format!("solidcraft-urdf-{tag}-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&d);
let _ = std::fs::create_dir_all(&d);
d
+6 -3
View File
@@ -18,13 +18,16 @@ use solidcraft_doc::Document;
use crate::{EngineError, Result, Session};
/// The recovery folder: `SOLIDCRAFT_RECOVERY_DIR`, else the platform's per-user data folder.
/// Spelled with long names (`vfs::long_names`): an agent's commands reach it by this path, and
/// short (8.3) names are refused there.
pub fn default_dir() -> Option<PathBuf> {
use solidcraft_io::vfs::long_names;
// Tests never touch the user's real recovery folder.
if cfg!(test) {
return Some(std::env::temp_dir().join(format!("solidcraft-test-recovery-{}", std::process::id())));
return Some(solidcraft_io::vfs::temp_dir().join(format!("solidcraft-test-recovery-{}", std::process::id())));
}
if let Some(d) = solidcraft_geom::env::var_os("RECOVERY_DIR").filter(|d| !d.is_empty()) {
return Some(PathBuf::from(d));
return Some(long_names(Path::new(&d)));
}
let env = |k: &str| std::env::var_os(k).filter(|d| !d.is_empty()).map(PathBuf::from);
let root = if cfg!(windows) {
@@ -34,7 +37,7 @@ pub fn default_dir() -> Option<PathBuf> {
} else {
env("XDG_DATA_HOME").or_else(|| env("HOME").map(|h| h.join(".local/share")))?
};
let (dir, legacy) = dirs_under(&root, cfg!(windows) || cfg!(target_os = "macos"));
let (dir, legacy) = dirs_under(&long_names(&root), cfg!(windows) || cfg!(target_os = "macos"));
// Compatibility shim (docs/compatibility.md): autosaves made before the rename (or, in the
// Flatpak sandbox, under the old app id) are copied to the new folder on first launch; the
// old folder is left as it was.
+1 -1
View File
@@ -8,7 +8,7 @@ use crate::*;
#[test]
fn file_commands_stay_inside_the_agents_folders() {
let base = std::env::temp_dir().join(format!("solidcraft-path-scope-{}", std::process::id()));
let base = solidcraft_io::vfs::temp_dir().join(format!("solidcraft-path-scope-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&base);
let (root, out) = (base.join("root"), base.join("out"));
std::fs::create_dir_all(&root).unwrap();