feat(execd): add directory listing endpoint#1001
Conversation
There was a problem hiding this comment.
Overall solid PR. Clean API design, thorough cross-SDK coverage, good test cases (symlink, depth=0, invalid input table tests).
Findings:
C# ListDirectoryAsync null depth: new Dictionary<string, string?> { ["depth"] = depth?.ToString() } — when depth is null, query string becomes ?path=/foo&depth=. execd returns 400 for invalid depth. Should omit the param entirely when null, or default to "1".
listDirectoryEntries duplicated verbatim in filesystem.go + filesystem_windows.go: Identical function in both files. Follows existing pattern (SearchFiles, MakeDirs, RemoveDirs are likewise duplicated) so not blocking, but worth noting future refactor could extract to shared file.
Non-blocking: Go SDK ListDirectory(ctx, path, depth int) always sends depth (incl 0) while every other SDK makes depth optional/nullable. Consistent but different API ergonomics.
|
Great Job! Please rebase main for conflicts 😊 |
Add GET /directories/list with depth control and FileInfo entry types across execd, specs, and sandbox SDKs. Include regression coverage for depth handling and symlink typing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Update the execd spec README endpoint lists for GET /directories/list. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5266899 to
c378238
Compare
|
Rebased onto latest main and resolved conflicts. Re-ran focused local checks successfully. |
Build the directory listing query parameters without depth when the optional value is null, and cover that behavior in adapter tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Addressed the C# null depth review comment: now only adds the query parameter when a value is provided, and the adapter test covers both and omitted depth. Verified with (111 passed). |
|
Addressed the C# null depth review comment:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: be5fced0be
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
One more SDK/API-surface suggestion after looking at the spec and Kotlin/Java usage more closely.
The current shape is good and consistent with the existing execd filesystem APIs, but two behavioral details should be part of the public contract rather than only mentioned in the PR body:
These details matter for SDKs and UI/file-browser clients.
The Kotlin API currently uses a default nullable parameter: fun listDirectory(
path: String,
depth: Int? = null,
): List<EntryInfo>This is fine for Kotlin callers, but Java callers do not get a natural optional-parameter call site and would need to pass sandbox.getFiles().listDirectory("/workspace/project", null);Since the spec defines fun listDirectory(path: String): List<EntryInfo> {
return listDirectory(path, null)
}
fun listDirectory(
path: String,
depth: Int?,
): List<EntryInfo>Then Java users can call: List<EntryInfo> entries = sandbox.getFiles().listDirectory("/workspace/project");
List<EntryInfo> nested = sandbox.getFiles().listDirectory("/workspace/project", 2);I do not think this needs a request/builder object yet. The API currently only has |
|
Also applies to the Go SDK surface. The spec makes ListDirectory(ctx, path, depth int)That makes the default-depth behavior less natural than the spec and the other SDKs. Since Go does not have default parameters or overloads, I suggest exposing the default case explicitly, for example: func (s *Sandbox) ListDirectory(ctx context.Context, path string) ([]FileInfo, error)
func (s *Sandbox) ListDirectoryWithDepth(ctx context.Context, path string, depth int) ([]FileInfo, error)Then callers can naturally use the API default: entries, err := sandbox.ListDirectory(ctx, "/workspace/project") // depth defaults to 1
nested, err := sandbox.ListDirectoryWithDepth(ctx, "/workspace/project", 2)
empty, err := sandbox.ListDirectoryWithDepth(ctx, "/workspace/project", 0)I would avoid introducing an options/request object for now because the endpoint only has |
Summary
GET /directories/listto execd withdepth-controlled directory traversalFileInfo.type(file,directory,symlink,other) and preserve symlink type viaLstatDesign notes
depthdefaults to1, which lists only immediate children.depth=0is accepted and returns an empty list because the root directory itself is not included.type=symlinkand are not recursively traversed by/directories/list./files/infonow usesLstatso symlinks are reported as symlinks instead of being resolved to their target type.FileInfo.typeis optional in the schema.Verification
cd components/execd && go test ./pkg/web/controllercd sdks/sandbox/go && go test ./...cd sdks/sandbox/javascript && pnpm run typecheckcd sdks/sandbox/python && uv run pytest tests/test_models_stability.py -q && uv run pyrightcd sdks/sandbox/kotlin && JAVA_HOME=$(/usr/libexec/java_home -v 17) ./gradlew :sandbox:testcd sdks/sandbox/csharp && PATH="$HOME/.dotnet:$PATH" dotnet test OpenSandbox.slngit diff --checkCloses #973
🤖 Generated with Claude Code