Add a bounded filesystem walk RPC (#29841)

Stack 1 of 3. Follow-ups: #29842 and #29844.

## What changes

Adds a general bounded `fs/walk` operation to the exec server.

The operation returns file and directory entries plus recoverable
per-path errors. It skips symlinks, preserves the existing filesystem
sandbox routing, and enforces depth, directory, entry, and response-size
limits.

This PR only defines and wires the filesystem operation. It does not
change any callers yet.
This commit is contained in:
jif
2026-06-24 16:05:43 +01:00
committed by GitHub
Unverified
parent b4f0f3eff1
commit c14623d04c
13 changed files with 608 additions and 0 deletions
@@ -33,6 +33,8 @@ use crate::protocol::FsReadFileParams;
use crate::protocol::FsReadFileResponse;
use crate::protocol::FsRemoveParams;
use crate::protocol::FsRemoveResponse;
use crate::protocol::FsWalkParams;
use crate::protocol::FsWalkResponse;
use crate::protocol::FsWriteFileParams;
use crate::protocol::FsWriteFileResponse;
use crate::rpc::internal_error;
@@ -198,6 +200,16 @@ impl FileSystemHandler {
Ok(FsReadDirectoryResponse { entries })
}
pub(crate) async fn walk(
&self,
params: FsWalkParams,
) -> Result<FsWalkResponse, JSONRPCErrorError> {
self.file_system
.walk(&params.path, params.options, params.sandbox.as_ref())
.await
.map_err(map_fs_error)
}
pub(crate) async fn remove(
&self,
params: FsRemoveParams,
@@ -37,6 +37,8 @@ use crate::protocol::FsReadFileParams;
use crate::protocol::FsReadFileResponse;
use crate::protocol::FsRemoveParams;
use crate::protocol::FsRemoveResponse;
use crate::protocol::FsWalkParams;
use crate::protocol::FsWalkResponse;
use crate::protocol::FsWriteFileParams;
use crate::protocol::FsWriteFileResponse;
use crate::protocol::HttpRequestParams;
@@ -311,6 +313,14 @@ impl ExecServerHandler {
self.file_system.read_directory(params).await
}
pub(crate) async fn fs_walk(
&self,
params: FsWalkParams,
) -> Result<FsWalkResponse, JSONRPCErrorError> {
self.require_initialized_for("filesystem")?;
self.file_system.walk(params).await
}
pub(crate) async fn fs_remove(
&self,
params: FsRemoveParams,
@@ -17,6 +17,7 @@ use crate::protocol::FS_READ_BLOCK_METHOD;
use crate::protocol::FS_READ_DIRECTORY_METHOD;
use crate::protocol::FS_READ_FILE_METHOD;
use crate::protocol::FS_REMOVE_METHOD;
use crate::protocol::FS_WALK_METHOD;
use crate::protocol::FS_WRITE_FILE_METHOD;
use crate::protocol::FsCanonicalizeParams;
use crate::protocol::FsCloseParams;
@@ -28,6 +29,7 @@ use crate::protocol::FsReadBlockParams;
use crate::protocol::FsReadDirectoryParams;
use crate::protocol::FsReadFileParams;
use crate::protocol::FsRemoveParams;
use crate::protocol::FsWalkParams;
use crate::protocol::FsWriteFileParams;
use crate::protocol::HTTP_REQUEST_METHOD;
use crate::protocol::HttpRequestParams;
@@ -147,6 +149,12 @@ pub(crate) fn build_router() -> RpcRouter<ExecServerHandler> {
handler.fs_read_directory(params).await
},
);
router.request(
FS_WALK_METHOD,
|handler: Arc<ExecServerHandler>, params: FsWalkParams| async move {
handler.fs_walk(params).await
},
);
router.request(
FS_REMOVE_METHOD,
|handler: Arc<ExecServerHandler>, params: FsRemoveParams| async move {