Multiplex a command's stdout, stderr, and exit code into a single JSONL stream
Project description
monopipe
Multiplex a command's stdout, stderr, and exit code into a single ordered JSONL stream — and demultiplex it back into the original channels.
Why?
When you capture a program's output to a file or send it down a pipe, you lose information: stdout and stderr collapse into one undifferentiated blob (or one of them is thrown away), the interleaving order is muddied, and the exit code vanishes entirely. monopipe records all of it — both channels, in arrival order, plus the return code — as one line-delimited JSON stream you can store, transport, or process, then replays it faithfully into real stdout and stderr later.
It runs like the time command: put monopipe in front of any command.
Quick Start
Install
pip install monopipe
Or run directly with uv:
uvx monopipe -- your-command --flag
Capture
monopipe ./build.sh --verbose > run.jsonl
This runs ./build.sh --verbose and writes a JSONL record stream to stdout:
{"start":["./build.sh","--verbose"]}
{"stdout":"Compiling...\n"}
{"stderr":"warning: unused variable\n"}
{"stdout":"Done\n"}
{"retcode":0}
Split
Feed that stream back in on stdin with -s to demultiplex it:
monopipe -s < run.jsonl # stdout → stdout, stderr → stderr
echo $? # → the original command's exit code
The Format
One JSON object per line, each (when produced by monopipe) carrying exactly one key:
| Key | Value |
|---|---|
start |
array of strings — the command and its arguments |
stdout / stderr |
string — a chunk of output, when it is valid UTF-8 |
stdout_b64 / stderr_b64 |
string — base64 of the raw bytes, for non-UTF-8 output |
retcode |
integer — the command's exit code |
Text is kept human-readable in the common case; arbitrary binary output falls back to base64 so the round-trip is always byte-exact. Split mode is lenient: it ignores unrecognised keys, accepts multiple recognised keys on one line, and skips lines that carry none.
How It Works
In capture mode, monopipe runs the child with its own stdin forwarded through (so interactive programs and filters still work), reads stdout and stderr concurrently, and emits one record per output line — or per 512 bytes when a line is longer — through a single serialised writer, so the JSONL is always well-formed and streamed in real time. The child's exit code is emitted last as a retcode record.
In split mode, monopipe reads the JSONL on stdin, writes each chunk to the matching channel, and exits with the recorded retcode so it stays transparent in a pipeline.
The binary is a statically-linked Go executable with zero external dependencies — distributed as platform-specific Python wheels via bin2whl, so pip install monopipe needs no Python runtime at execution time.
Licence
Released under the Unlicense — public domain.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file monopipe-1.0.0b1-py3-none-win_arm64.whl.
File metadata
- Download URL: monopipe-1.0.0b1-py3-none-win_arm64.whl
- Upload date:
- Size: 954.7 kB
- Tags: Python 3, Windows ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a32443743d9ee29f4ef96fce60f27741d53018149f068dd09175934f232cb6d
|
|
| MD5 |
46261b7386e331c2ab627de5f9a00117
|
|
| BLAKE2b-256 |
2ec042e6f1e5615e9a98bc3ac34b4dbad55cdaab86f01fefb1524d9bb077298d
|
File details
Details for the file monopipe-1.0.0b1-py3-none-win_amd64.whl.
File metadata
- Download URL: monopipe-1.0.0b1-py3-none-win_amd64.whl
- Upload date:
- Size: 1.1 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c077d4acbd76c4395c1f26c2162e92fd85b879309c6dd55c7b23a393c500bf94
|
|
| MD5 |
448dec98f817ccafc831c27421d839c7
|
|
| BLAKE2b-256 |
311b27785890bcac90c65a8e3b90c167dc22c096fc97900542aa21633d243d3c
|
File details
Details for the file monopipe-1.0.0b1-py3-none-manylinux_2_17_x86_64.whl.
File metadata
- Download URL: monopipe-1.0.0b1-py3-none-manylinux_2_17_x86_64.whl
- Upload date:
- Size: 1.0 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7a9e578ba29951bb4243ed60beb54197d6bf6dceaa434451896ad3fa19ee9482
|
|
| MD5 |
9f1bd5c8808d3cd31566f819a5ad89ad
|
|
| BLAKE2b-256 |
2acf7156a35e88e21313c68ed929a6f16ffdfd13709e0cbb6bb7e60a91f25ae4
|
File details
Details for the file monopipe-1.0.0b1-py3-none-manylinux_2_17_aarch64.whl.
File metadata
- Download URL: monopipe-1.0.0b1-py3-none-manylinux_2_17_aarch64.whl
- Upload date:
- Size: 932.5 kB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
317e260eb6b3f16c0685b6fb9eefe8b93d440e19aac9e34949c15cce28fa0b99
|
|
| MD5 |
e75eadae2e1606802543aab86d9fd7f9
|
|
| BLAKE2b-256 |
8d53f3b49f44168cde2fca82851596710c78d7be34db2a9cd366b07535a3811e
|
File details
Details for the file monopipe-1.0.0b1-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: monopipe-1.0.0b1-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 930.9 kB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d31c5adfda25c23d0db37284701c3b4744c57956c1379cce40226f5d95207c44
|
|
| MD5 |
309a24e36b4319928bfcc61dac4bb33c
|
|
| BLAKE2b-256 |
ea33c5313c2bf7dab9133b799a8e39bb3fdc9a45682141e34249abf485264f5f
|
File details
Details for the file monopipe-1.0.0b1-py3-none-macosx_10_9_x86_64.whl.
File metadata
- Download URL: monopipe-1.0.0b1-py3-none-macosx_10_9_x86_64.whl
- Upload date:
- Size: 1.0 MB
- Tags: Python 3, macOS 10.9+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1b07910ddbcaac0c6b46f7c12580296dab0be2e97259a1dca4adb8ff9615f11
|
|
| MD5 |
62b341d1f11116253e0f5022b6060426
|
|
| BLAKE2b-256 |
c06722aa3b07d256387451315b6ed53e2b5ac82e3f278a674366351ffb1ea966
|