Repository navigation
feat(streaming): add live command I/O and async output sinks - #2741
Merged
Merged
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
bashkit | 4af2b7a | Commit Preview URL Branch Preview URL |
Oct 16 2026, 09:56 PM |
chaliy
force-pushed
the
feat/streaming-command-io
branch
from
October 16, 2026 21:33
b880eac to
5f9bf33
Compare
chaliy
force-pushed
the
feat/streaming-command-io
branch
from
October 16, 2026 21:55
5f9bf33 to
4af2b7a
Compare
2 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Custom commands can read stdin incrementally and await byte writes to stdout/stderr while a script runs. Rust, native Python, native JavaScript and browser/worker WASM expose live handlers, async output sinks and bounded capture. The CLI delivers output through the same execution driver; the C ABI adds synchronous output callbacks.
Capture and delivery are independent: callers can stream without retaining final output, capture a bounded copy, or do both. Pipes apply backpressure, shell redirections preserve descriptor order, and cancellation/deadlines cover pending handlers and sinks. Request-scoped I/O and filesystem capabilities expire when execution ends.
Native JS command I/O uses validated opaque handles and clones Rust capabilities before async work, avoiding generated class pointer conversions. Forged and cross-type handles fail at the boundary. Python/TypeScript runtime host functions use the same execution-local dispatcher with buffered calls, live byte sinks and explicit capture; host functions and sinks retain caller async context. C runtime host functions also work during streaming execution; both execution entry points share callback admission guards, and blocking calls from output callbacks fail before locking or nesting runtimes.
Public guides include runnable Rust/Python/JS/WASM examples, migration instructions, remaining buffering boundaries and a per-surface support matrix. The Rust script-analysis enum is now
CommandPlacement;CommandContextnames the running handler's capabilities.Why
The buffered custom-command contract and synchronous output observers cannot support consumers that need incremental input, awaited output and bounded retention. This addresses that handler/execution boundary and documents the remaining whole-buffer roadmap.
Before / After
printf hello | copypasses bytes through an async reader/writer handler; Rust.stdout(writer).capture(1024), Pythonstdout=sink, capture=1024, and JS{stdout: sink, capture: 1024}select delivery and capture explicitly./dev/fdinstead of leaking them to the caller's sinks. Cancelled Python requests queued behind another handler cannot start filesystem side effects. Deep substitution tests exercise both buffered and live execution; pipeline futures have a separate heap boundary to preserve recursive stack limits.Risk
CommandPlacement. RustBash::executediscards output unless capture is selected; bufferedexecremains available. Python/JS ordinary execution keeps bounded capture.Checklist
Validation includes Rust unit/integration/CLI and Rustdoc tests, native Python and Node/Bun/Deno tests, WASM package and real-browser tests, 32 C ABI tests and four compiled C11 examples plus a C++17 header check after rebasing onto the C host-function API, lint/type checks, documentation/site checks and saved performance runs. Final CI results are required before merge.
The final local pass includes 2,206 Rust integration tests (four existing ignores), 939 Python tests (16 optional skips), 20 repeated runs of eight queued-cancellation cases, 681 native JS AVA tests, 172 Node and Bun compatibility tests each, Deno compatibility tests (32 tests / 163 nested steps), queued live Python/TypeScript host-function context and cancellation regressions after rebasing onto current main, TypeScript checks, all-features Clippy with warnings denied, cargo-vet, Python lint and repository documentation/script checks. The workspace-wide
just pre-prtest link exhausted this environment's 32 GB disk; scoped tests completed after clearing build caches, and the full CI matrix validates the PR before merge.The post-fix parallel-execution benchmark also completed in the dev profile. Its timings are not compared with the saved release-profile results.