llm-sh
An embeddable bash-compatible shell that minimizes its own output, for LLM agents.
The shell runs in this process. Common commands — cat, grep, sed, ls,
find, sort, jq, diff, and about fifty more — are implemented in Rust
rather than executed as child processes, so they need no system binaries and
cost no fork/exec. Each command's output is then passed through a per-tool
minimizer before it reaches your context, with the full capture kept for when
you need it.
git log -n 60 22,509 → 9,386 bytes (-58%)
ls -la 3,288 → 920 bytes (-72%)
Status: alpha. Published on PyPI as
llmbash(the namellm-shcollides with existing packages); wheels are also built locally. API is expected to change.
Install
pip install llmbash
Requires Python 3.11+. One abi3 wheel covers 3.11 and later; no Rust toolchain
is needed at install time.
Quickstart
import asyncio, llm_sh
async def main():
shell = llm_sh.Session() # one persistent shell
result = await shell.run("cargo test", cwd="/repo")
print(result.exit_code) # 0
print(result.output) # minimized transcript
if result.original is not None: # only when a filter rewrote it
print(result.input_bytes, "→", result.output_bytes)
asyncio.run(main())
Streaming, as output is produced:
async for chunk in shell.stream("make -j8"):
if chunk.kind == "output":
print(chunk.data, end="")
else: # kind == "exit"
print("exit", chunk.result.exit_code)
API
Session(*, session_env=None, minimize=True) |
A persistent shell. Creating one is cheap. |
await session.run(cmd, *, cwd=None, env=None, timeout_ms=None) |
Run to completion → RunResult. |
session.stream(cmd, *, ...) |
Async iterator of Chunk: "output" items, then one "exit". |
await session.abort() |
Abort the command currently running. |
await session.live_background_job_count() |
Live & / nohup children. |
RunResult: exit_code, output, original, filter, input_bytes,
output_bytes, cancelled, timed_out, working_dir.
Semantics worth knowing
- A session is stateful.
cwd, exported variables and shell functions survive across calls:await s.run("cd /tmp")affects the nextrun. Relative paths resolve against the session's directory, never the host process's. - A session runs its own commands one at a time. There is a single shell
state behind it, so concurrent awaits on the same session queue up. Use
separate sessions for parallelism —
asyncio.gather(s1.run(a), s2.run(b))really does run both at once. - Cancellation reaches the children. Cancelling an await (or hitting Ctrl-C)
aborts the command and kills its process group. Abandoning a
stream()iterator does the same. - A timeout is not an exception.
timeout_mscomes back astimed_out=True; the partial output is preserved. - A non-zero exit is not an exception. Check
exit_code. - Output is one merged transcript on both
runandstream, matching the minimizer's contract.stderris not separated.
What gets minimized
filter names the filter that produced output ("git", "ls",
"pipeline:gradle") or the reason none did ("piped", "too-short",
"disabled"). A pipeline's output is deliberately left alone: if you are
piping through jq or awk, you are parsing it, and rewriting it would be
wrong.
original is populated only when a filter actually rewrote the output. Persist
it if you want to offer a "show me the full output" handle later.
What's inside
The shell engine is a fork of brush's
brush-core; the in-process utilities are ports of
uutils coreutils/findutils/sed,
jaq, and moreutils-inspired implementations;
search is backed by ripgrep's crates.
Consequently a wheel is not small (~9 MB compressed): every bundled command is
reachable at runtime, so nothing can be pruned away.
This package is a thin Python layer over the Rust shell, which lives in
oh-my-pi — itself a fork of
Pi by Mario Zechner. All MIT, with the
third-party notices reproduced in that repository.
License
MIT.
Metadata
Release files for llmbash 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| llmbash-0.1.0.tar.gz | 47.1 kB | Without provenance | Details for llmbash-0.1.0.tar.gz |
Built distributions (wheels)
| File | Actions Reset | |||
|---|---|---|---|---|
| llmbash-0.1.0-cp311-abi3-win_amd64.whl | CPython 3.11 | abi3 | Windows x86-64 | Details for llmbash-0.1.0-cp311-abi3-win_amd64.whl |
| llmbash-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.11 | abi3 | Linux glibc 2.17+ x86-64 | Details for llmbash-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
| llmbash-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.11 | abi3 | Linux glibc 2.17+ ARM64 | Details for llmbash-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
| llmbash-0.1.0-cp311-abi3-macosx_11_0_arm64.whl | CPython 3.11 | abi3 | macOS 11.0+ ARM64 | Details for llmbash-0.1.0-cp311-abi3-macosx_11_0_arm64.whl |
| llmbash-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl | CPython 3.11 | abi3 | macOS 10.12+ x86-64 | Details for llmbash-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl |
Total release size: 44.9 MB
Release files / llmbash-0.1.0.tar.gz
| Download URL | llmbash-0.1.0.tar.gz |
|---|---|
| Size | 47.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6581c5ed30d0bdaa5aa8c28052d27d6108102cb151ed012b9d74c6fac17477df
|
|
BLAKE2b-256 checksum How to use checksums |
df59813788812997a007bdd4f24f7d9025210459908c25afed22fa6ee6172fcc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / llmbash-0.1.0-cp311-abi3-win_amd64.whl
| Download URL | llmbash-0.1.0-cp311-abi3-win_amd64.whl |
|---|---|
| Size | 9.8 MB |
| Tags | CPython 3.11 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
4a38e3c6456d0679e4f25da4b43bc621acd59ffaae9772ffefb7f39261826555
|
|
BLAKE2b-256 checksum How to use checksums |
797fae17f3d707024f5457a44043ec7ecdf89a44546c10bc30ffc13c7c5dbe21
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / llmbash-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | llmbash-0.1.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 9.3 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
613a219d07de10ef695ed2db4612bd1d869ba7cb9cdff564d2314ba965c1a330
|
|
BLAKE2b-256 checksum How to use checksums |
e129f167f4708a913507c35a4be7dbdca045763325b57d5d2b4c5b23e7ced9b4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / llmbash-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | llmbash-0.1.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 8.8 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
13283f1821cf39e1a7a750dacdee5e7fb2b78f73f3d50600fb3c30f73304992e
|
|
BLAKE2b-256 checksum How to use checksums |
b7cdd55447ed9de74165cf7e21a690d10844b50f1f5bb96d226a9c8cc9cdf4ee
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / llmbash-0.1.0-cp311-abi3-macosx_11_0_arm64.whl
| Download URL | llmbash-0.1.0-cp311-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 8.0 MB |
| Tags | CPython 3.11 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
c7bdc613dcc01815dee2b2ae72215194ae730afc65523309d3b0f3f01ecf7051
|
|
BLAKE2b-256 checksum How to use checksums |
ada32862a7fcdad3936724ae4a201998c64e13e80dcd4f1d31c46d90367a0de7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / llmbash-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl
| Download URL | llmbash-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 9.0 MB |
| Tags | CPython 3.11 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
aef6e4fa3d6893281be37b7a1ec9da437283adccdba16cd007074dd95b7b1422
|
|
BLAKE2b-256 checksum How to use checksums |
f2b76e03a353ff3e88f0506cf72981494f653f9d2b7dfb5567395aee6e5d0064
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for llmbash 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.