Repository navigation
Description
User Story
As a client running a persistent command in an OpenShell sandbox, I want to send a request and read its response while keeping stdin open, so that I can exchange multiple requests with the same process without allocating a terminal.
Problem Statement
openshell sandbox exec reads piped stdin to EOF before starting the remote command. A client that writes one request and waits for a response cannot progress: OpenShell waits for EOF, while the client waits for a process that has not started.
Impact / Why This Matters
Finite pipelines can close stdin before reading results. Persistent request/response tools cannot do that without ending their input stream. Using a TTY can change byte handling and combines output that a client needs to read separately. Clients otherwise need a separate SSH or SDK integration for this workflow.
Proposed Design
Add an explicit openshell sandbox exec --name <sandbox> --stream-stdin -- <command> mode. Start the command before stdin reaches EOF and forward input as it arrives. Run without a TTY, keep stdout and stderr separate, and preserve the command's exit status after receiving the final stream result. Reject --tty with this mode; allow --no-tty.
Closing stdin ends only the command's input. Continue reading its remaining output until completion. Cancellation stops the execution and releases its input resources. Report transport or input-delivery failure even if the process previously reported exit code zero. Do not automatically retry an interrupted execution because the command may already have performed work.
Retain the existing 4 MiB total stdin limit per command. Exceeding it cancels the operation and reports that the command may already have processed earlier input. Cancellation cannot undo that work. The total limit bounds this CLI path even when the command stops reading stdin. Without the new flag, continue buffering finite input and rejecting oversized input before launch.
Acceptance Criteria
- A client completes two request/response exchanges with one remote process before closing stdin.
- Streaming mode allocates no TTY, preserves separate stdout and stderr bytes, and rejects
--tty. - After stdin EOF, the client receives remaining output and the command's exit status.
- Cancellation and input-delivery failure stop the operation and release input resources.
- Input remains limited to 4 MiB per command; exceeding the limit fails with a diagnostic about possible partial processing.
- A transport failure is reported as failure, with no automatic second execution.
- Existing finite piped-input behavior continues to work without the new flag.
Alternatives Considered
Make every pipe stream automatically. An explicit mode makes the changed execution timing visible and keeps existing finite-input behavior intact. Use a TTY. That changes terminal semantics and does not meet the separate-output requirement. Use an SDK directly. That is suitable for applications already using an SDK, but leaves command-line integrations without this workflow.
Agent Investigation
No response
Checklist
- I've reviewed existing issues and the architecture docs
- This is a design proposal, not a "please build this" request
Activity
johntmyers commentedon Sep 30, 2026
What's the use case that was encountered that requires this?
shiju-nv commentedon Sep 30, 2026
The use case is a script controlling a process inside a sandbox: make a request, read its response, change credentials or policy on the host, then make another request without restarting the process.
With the proposed --stream-stdin flag, we'd launch the script using:
openshell sandbox exec --name test-sandbox --stream-stdin --no-tty -- python3 -u /sandbox/worker.pyA controller would use that command through subprocess pipes:
Currently, the CLI waits for stdin EOF before starting the remote command, so the first response cannot arrive. We need non-TTY execution to keep requests and responses unchanged and keep stdout separate from stderr.
Without --stream-stdin, that sequence is:
johntmyers commentedon Oct 2, 2026
I was able to achieve this now that #4006 has landed. @shiju-nv can you please try this again and close the issue and PR if things are working on your end,
shiju-nv commentedon Oct 2, 2026
Tried it on a new sandbox. On CLI
0.1.3-dev.66+g36819f476, sandbox exec --no-tty starts streaming when piped stdin stays open past the 200 ms grace period. That lets a client send requests and get replies from the same remote process without closing stdin.I've narrowed #3803 to report gRPC errors that arrive after the remote command exits and add a warning when streaming exceeds the 4 MiB limit, since the command may already have processed some input.