Skip to content

feat(execd): add directory listing endpoint#1001

Open
asiudgufgbukbsa wants to merge 3 commits into
opensandbox-group:mainfrom
asiudgufgbukbsa:feat/directories-list-depth
Open

feat(execd): add directory listing endpoint#1001
asiudgufgbukbsa wants to merge 3 commits into
opensandbox-group:mainfrom
asiudgufgbukbsa:feat/directories-list-depth

Conversation

@asiudgufgbukbsa

Copy link
Copy Markdown
Contributor

Summary

  • add GET /directories/list to execd with depth-controlled directory traversal
  • add FileInfo.type (file, directory, symlink, other) and preserve symlink type via Lstat
  • expose directory listing and entry type support across Python, JavaScript, Go, Kotlin, and C# sandbox SDKs

Design notes

  • depth defaults to 1, which lists only immediate children.
  • depth=0 is accepted and returns an empty list because the root directory itself is not included.
  • Symlinks are reported as type=symlink and are not recursively traversed by /directories/list.
  • /files/info now uses Lstat so symlinks are reported as symlinks instead of being resolved to their target type.
  • The public spec remains additive/backward-compatible: FileInfo.type is optional in the schema.

Verification

  • cd components/execd && go test ./pkg/web/controller
  • cd sdks/sandbox/go && go test ./...
  • cd sdks/sandbox/javascript && pnpm run typecheck
  • cd sdks/sandbox/python && uv run pytest tests/test_models_stability.py -q && uv run pyright
  • cd sdks/sandbox/kotlin && JAVA_HOME=$(/usr/libexec/java_home -v 17) ./gradlew :sandbox:test
  • cd sdks/sandbox/csharp && PATH="$HOME/.dotnet:$PATH" dotnet test OpenSandbox.sln
  • git diff --check

Closes #973

🤖 Generated with Claude Code

@Pangjiping Pangjiping left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread sdks/sandbox/csharp/src/OpenSandbox/Adapters/FilesystemAdapter.cs
Comment thread components/execd/pkg/web/controller/filesystem.go
@Pangjiping

Copy link
Copy Markdown
Collaborator

Great Job! Please rebase main for conflicts 😊

asiudgufgbukbsa and others added 2 commits June 8, 2026 18:53
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>
@asiudgufgbukbsa asiudgufgbukbsa force-pushed the feat/directories-list-depth branch from 5266899 to c378238 Compare June 8, 2026 10:56
@asiudgufgbukbsa

Copy link
Copy Markdown
Contributor Author

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>
@asiudgufgbukbsa

Copy link
Copy Markdown
Contributor Author

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).

@asiudgufgbukbsa

Copy link
Copy Markdown
Contributor Author

Addressed the C# null depth review comment:

  • ListDirectoryAsync now only adds the depth query parameter when a value is provided.
  • FilesystemAdapterTests now covers both depth=0 and omitted depth.
  • Verified with: dotnet test OpenSandbox.sln (111 passed).

@Pangjiping Pangjiping self-requested a review June 8, 2026 11:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread sdks/sandbox/csharp/src/OpenSandbox/Services/ISandboxFiles.cs

@Pangjiping Pangjiping left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ninan-nn

ninan-nn commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

One more SDK/API-surface suggestion after looking at the spec and Kotlin/Java usage more closely.

  1. Please tighten the /directories/list spec description a bit.

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:

  • Symbolic links are reported as type=symlink and are not recursively traversed by directory listing.
  • The response ordering should be clarified. If the implementation intends to provide stable ordering, document it, e.g. lexical order by entry name/path. If not, explicitly say the order is not guaranteed.

These details matter for SDKs and UI/file-browser clients.

  1. Please add a Java-friendly Kotlin overload for the optional depth parameter.

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 null explicitly:

sandbox.getFiles().listDirectory("/workspace/project", null);

Since the spec defines depth as optional/defaulting to 1, the SDK surface should expose that naturally to Java as well. I suggest adding an overload/default method:

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 path and optional depth, so overloads keep the surface simpler. A request object can still be added later if this grows pagination/sorting/filtering options.

@ninan-nn

ninan-nn commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Also applies to the Go SDK surface.

The spec makes depth optional with default 1, but the current Go API requires callers to always pass it:

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 path and optional depth. A small pair of methods keeps the Go API simple while still matching the spec's optional/default semantics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] add /directories/list endpoint for listing directory contents with depth control

3 participants