summaryrefslogtreecommitdiff
path: root/src/Agent.Windows/Tools/WindowsToolBackend.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Agent.Windows/Tools/WindowsToolBackend.cs')
-rw-r--r--src/Agent.Windows/Tools/WindowsToolBackend.cs16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/Agent.Windows/Tools/WindowsToolBackend.cs b/src/Agent.Windows/Tools/WindowsToolBackend.cs
index bb54c6e..936bcbd 100644
--- a/src/Agent.Windows/Tools/WindowsToolBackend.cs
+++ b/src/Agent.Windows/Tools/WindowsToolBackend.cs
@@ -104,6 +104,7 @@ public sealed class WindowsToolBackend(WindowsSandboxSettings settings, ISecurit
int lines = arguments.TryGetProperty("tail_lines", out JsonElement lineElement) ? lineElement.GetInt32() : 100;
lines = Math.Min(lines, settings.TailLineLimit);
if (new FileInfo(canonical).Length > settings.WholeReadLimitBytes * 16) throw new IOException("Tail input is too large.");
+ if (!TextFileDetector.IsText(canonical)) throw new ToolValidationException("File appears to be binary; tail mode is text-only.");
string[] content = File.ReadLines(canonical).TakeLast(lines).ToArray();
return Success(JsonSerializer.Serialize(content));
}
@@ -160,6 +161,14 @@ public sealed class WindowsToolBackend(WindowsSandboxSettings settings, ISecurit
FileDeleteTransaction transaction = editor.Delete(path, expected);
transaction.Commit();
}
+ else if (operation == "rename")
+ {
+ string newPath = arguments.GetProperty("new_path").GetString()!;
+ _paths.Demand(path, FileCapability.Write);
+ _paths.Demand(newPath, FileCapability.Write);
+ FileRenameTransaction transaction = editor.Rename(path, newPath);
+ transaction.Commit();
+ }
else
{
_paths.Demand(path, FileCapability.Write);
@@ -169,8 +178,11 @@ public sealed class WindowsToolBackend(WindowsSandboxSettings settings, ISecurit
FileEditTransaction transaction = editor.Replace(path, replacement, expected);
transaction.Commit();
}
- audit.Write(new(DateTimeOffset.UtcNow, context.Journal.TaskId, "file." + operation, "completed", new Dictionary<string, string> { ["path"] = Path.GetFullPath(path) }));
- return Success($"{operation} completed for {Path.GetFullPath(path)}", externalEffect: true);
+ string auditPath = operation == "rename"
+ ? $"{Path.GetFullPath(path)} -> {Path.GetFullPath(arguments.GetProperty("new_path").GetString()!)}"
+ : Path.GetFullPath(path);
+ audit.Write(new(DateTimeOffset.UtcNow, context.Journal.TaskId, "file." + operation, "completed", new Dictionary<string, string> { ["path"] = auditPath }));
+ return Success($"{operation} completed for {auditPath}", externalEffect: true);
}
private ToolExecutionResult DirectoryOp(TaskContext context, JsonElement arguments)