feat(sandbox): runCommand timeout/AbortSignal and file ops#122
feat(sandbox): runCommand timeout/AbortSignal and file ops#122jamie-at-bunny wants to merge 3 commits into
Conversation
…, deleteFile, rename, exists)
|
@codex review |
🦋 Changeset detectedLatest commit: 9d50346 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7fe65490f8
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| }); | ||
| }); | ||
| async exec(command: string, limits?: ExecLimits): Promise<ExecResult> { | ||
| return collectExec(await this.execStream(command), limits); |
There was a problem hiding this comment.
Honor AbortSignal before opening SSH exec
When limits.signal is already aborted, or aborts while the SSH channel is being opened, this still awaits execStream(command) first, so the remote command can be created and begin running before collectExec notices the cancellation. For callers that pass a shared or timed-out signal to prevent side effects, commands like file mutations or network calls can still execute briefly; check/race the signal before and during channel creation instead of only after the exec request succeeds.
Useful? React with 👍 / 👎.
| async runCommand( | ||
| command: RunCommandOptions & { detached: true }, | ||
| ): Promise<Command>; | ||
| async runCommand(command: RunCommandOptions): Promise<CommandFinished>; |
There was a problem hiding this comment.
Preserve union return for dynamic detached options
When callers build an options object in a variable typed as RunCommandOptions (for example from a helper or config) and set detached: true, overload resolution falls through to this catch-all and types the result as CommandFinished, even though the runtime branch still returns a live Command. That lets consumer code type-check while treating a still-running command as finished (or prevents access to logs()/kill() without casts); narrow this overload to non-detached options or return the union for dynamic inputs.
Useful? React with 👍 / 👎.
| /** Kill the command and reject with CommandTimeoutError after this many milliseconds. */ | ||
| timeout?: number; | ||
| /** Abort to kill the command and reject with the signal's reason. */ | ||
| signal?: AbortSignal; |
There was a problem hiding this comment.
Split detached command options from blocking limits
Because timeout and signal live on the same public RunCommandOptions interface as detached, calls such as sandbox.runCommand({ cmd: "sleep", detached: true, timeout: 1000 }) type-check and even select the Promise<Command> overload, but the runtime validation throws for every such call. SDK users will only discover this unsupported combination at runtime; model the options as blocking-vs-detached unions so timeout/signal are not accepted with detached: true.
Useful? React with 👍 / 👎.
|
@codex re-review |
|
To use Codex here, create a Codex account and connect to github. |
@amir-at-bunny I'm experimenting with this for project "rabbit's foot".