@papercraneai/sandbox-agent 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +26 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { createServer } from "http";
|
|
|
4
4
|
import { WebSocketServer, WebSocket } from "ws";
|
|
5
5
|
import { Tail } from "tail";
|
|
6
6
|
import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
|
|
7
|
-
import { readdir, stat, mkdir, readFile, writeFile, access, unlink } from "fs/promises";
|
|
7
|
+
import { readdir, stat, mkdir, readFile, writeFile, access, unlink, rm } from "fs/promises";
|
|
8
8
|
import { join, dirname, resolve } from "path";
|
|
9
9
|
import { fileURLToPath } from "url";
|
|
10
10
|
import { spawn, execSync } from "child_process";
|
|
@@ -574,8 +574,12 @@ app.get("/files/read", async (req, res) => {
|
|
|
574
574
|
gif: "image/gif",
|
|
575
575
|
webp: "image/webp"
|
|
576
576
|
};
|
|
577
|
+
// Return relative path (strip PROJECT_DIR prefix) so CLI users see usable paths
|
|
578
|
+
const relativePath = fullPath.startsWith(PROJECT_DIR)
|
|
579
|
+
? fullPath.slice(PROJECT_DIR.length).replace(/^\/+/, "")
|
|
580
|
+
: fullPath;
|
|
577
581
|
res.json({
|
|
578
|
-
path:
|
|
582
|
+
path: relativePath,
|
|
579
583
|
name: fullPath.split("/").pop(),
|
|
580
584
|
content,
|
|
581
585
|
size: stats.size,
|
|
@@ -833,13 +837,17 @@ app.delete("/files/delete", async (req, res) => {
|
|
|
833
837
|
res.status(403).json({ error: "Access denied: path outside project directory" });
|
|
834
838
|
return;
|
|
835
839
|
}
|
|
836
|
-
//
|
|
840
|
+
// Prevent deleting the project root itself
|
|
841
|
+
if (resolvedPath === resolvedProject) {
|
|
842
|
+
res.status(400).json({ error: "Cannot delete the project root directory" });
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
const recursive = req.query.recursive === "true" || req.body?.recursive === true;
|
|
846
|
+
// Check if path exists
|
|
847
|
+
let isDirectory = false;
|
|
837
848
|
try {
|
|
838
849
|
const stats = await stat(fullPath);
|
|
839
|
-
|
|
840
|
-
res.status(400).json({ error: "Cannot delete a directory, only files", path: sanitizedPath });
|
|
841
|
-
return;
|
|
842
|
-
}
|
|
850
|
+
isDirectory = stats.isDirectory();
|
|
843
851
|
}
|
|
844
852
|
catch (error) {
|
|
845
853
|
if (error.code === "ENOENT") {
|
|
@@ -848,8 +856,17 @@ app.delete("/files/delete", async (req, res) => {
|
|
|
848
856
|
}
|
|
849
857
|
throw error;
|
|
850
858
|
}
|
|
851
|
-
|
|
852
|
-
|
|
859
|
+
if (isDirectory && !recursive) {
|
|
860
|
+
res.status(400).json({ error: "Cannot delete a directory without recursive flag", path: sanitizedPath });
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
// Delete file or directory
|
|
864
|
+
if (isDirectory) {
|
|
865
|
+
await rm(fullPath, { recursive: true });
|
|
866
|
+
}
|
|
867
|
+
else {
|
|
868
|
+
await unlink(fullPath);
|
|
869
|
+
}
|
|
853
870
|
log.info({ path: sanitizedPath }, "File deleted");
|
|
854
871
|
res.json({
|
|
855
872
|
success: true,
|