checkpoint

⚒️ Generated with [Fabro](https://fabro.sh)
This commit is contained in:
Fabro 2026-03-16 08:01:53 -04:00
parent 4fcf020ca0
commit d6d8663062
5 changed files with 186 additions and 28 deletions

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,5 @@
{
"command": "git diff",
"language": "shell",
"timeout_ms": null
}

View file

@ -0,0 +1,5 @@
{
"duration_ms": 87,
"exit_code": 0,
"timed_out": false
}

View file

@ -0,0 +1,6 @@
{
"status": "success",
"notes": "Script completed: git diff",
"failure_reason": null,
"timestamp": "2026-03-16T12:01:53.176125+00:00"
}

128
nodes/solve/diff.patch Normal file
View file

@ -0,0 +1,128 @@
diff --git a/lib/crates/fabro-agent/src/local_sandbox.rs b/lib/crates/fabro-agent/src/local_sandbox.rs
index 9798ea3..e93b170 100644
--- a/lib/crates/fabro-agent/src/local_sandbox.rs
+++ b/lib/crates/fabro-agent/src/local_sandbox.rs
@@ -71,6 +71,20 @@ impl LocalSandbox {
}
}
+#[cfg(unix)]
+async fn set_default_file_permissions(path: &Path) -> Result<(), String> {
+ use std::os::unix::fs::PermissionsExt;
+
+ tokio::fs::set_permissions(path, std::fs::Permissions::from_mode(0o644))
+ .await
+ .map_err(|e| format!("Failed to set permissions on {}: {e}", path.display()))
+}
+
+#[cfg(not(unix))]
+async fn set_default_file_permissions(_path: &Path) -> Result<(), String> {
+ Ok(())
+}
+
#[async_trait]
impl Sandbox for LocalSandbox {
async fn read_file(
@@ -96,7 +110,8 @@ impl Sandbox for LocalSandbox {
}
tokio::fs::write(&full_path, content)
.await
- .map_err(|e| format!("Failed to write {}: {e}", full_path.display()))
+ .map_err(|e| format!("Failed to write {}: {e}", full_path.display()))?;
+ set_default_file_permissions(&full_path).await
}
async fn delete_file(&self, path: &str) -> Result<(), String> {
@@ -379,6 +394,7 @@ impl Sandbox for LocalSandbox {
local_path.display()
)
})?;
+ set_default_file_permissions(local_path).await?;
Ok(())
}
@@ -400,6 +416,7 @@ impl Sandbox for LocalSandbox {
full_path.display()
)
})?;
+ set_default_file_permissions(&full_path).await?;
Ok(())
}
@@ -508,6 +525,13 @@ mod tests {
use super::*;
use std::path::PathBuf;
+ #[cfg(unix)]
+ fn file_mode(path: &Path) -> u32 {
+ use std::os::unix::fs::PermissionsExt;
+
+ std::fs::metadata(path).unwrap().permissions().mode() & 0o777
+ }
+
fn temp_dir() -> PathBuf {
let dir = std::env::temp_dir().join(format!("local_env_test_{}", uuid::Uuid::new_v4()));
std::fs::create_dir_all(&dir).unwrap();
@@ -560,6 +584,62 @@ mod tests {
std::fs::remove_dir_all(&dir).unwrap();
}
+ #[cfg(unix)]
+ #[tokio::test]
+ async fn write_file_sets_default_permissions() {
+ use std::os::unix::fs::PermissionsExt;
+
+ let dir = temp_dir();
+ let path = dir.join("private.txt");
+ std::fs::write(&path, "old").unwrap();
+ std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o600)).unwrap();
+
+ let env = LocalSandbox::new(dir.clone());
+ env.write_file("private.txt", "new").await.unwrap();
+
+ assert_eq!(file_mode(&path), 0o644);
+ std::fs::remove_dir_all(&dir).unwrap();
+ }
+
+ #[cfg(unix)]
+ #[tokio::test]
+ async fn upload_file_from_local_sets_default_permissions() {
+ use std::os::unix::fs::PermissionsExt;
+
+ let dir = temp_dir();
+ let scratch = temp_dir();
+ let src = scratch.join("upload.txt");
+ std::fs::write(&src, "content").unwrap();
+ std::fs::set_permissions(&src, std::fs::Permissions::from_mode(0o600)).unwrap();
+
+ let env = LocalSandbox::new(dir.clone());
+ env.upload_file_from_local(&src, "uploaded.txt").await.unwrap();
+
+ assert_eq!(file_mode(&dir.join("uploaded.txt")), 0o644);
+ std::fs::remove_dir_all(&dir).unwrap();
+ std::fs::remove_dir_all(&scratch).unwrap();
+ }
+
+ #[cfg(unix)]
+ #[tokio::test]
+ async fn download_file_to_local_sets_default_permissions() {
+ use std::os::unix::fs::PermissionsExt;
+
+ let dir = temp_dir();
+ let scratch = temp_dir();
+ let remote = dir.join("remote.txt");
+ let local = scratch.join("downloaded.txt");
+ std::fs::write(&remote, "content").unwrap();
+ std::fs::set_permissions(&remote, std::fs::Permissions::from_mode(0o600)).unwrap();
+
+ let env = LocalSandbox::new(dir.clone());
+ env.download_file_to_local("remote.txt", &local).await.unwrap();
+
+ assert_eq!(file_mode(&local), 0o644);
+ std::fs::remove_dir_all(&dir).unwrap();
+ std::fs::remove_dir_all(&scratch).unwrap();
+ }
+
#[tokio::test]
async fn file_exists_true() {
let dir = temp_dir();