Open Shell
A cross-platform shell whose pipeline carries JSON, not text.
Bash pipes text. PowerShell pipes .NET objects. Open Shell pipes JSON records — so every stage is structured, and the same pipeline works on Linux, macOS, and Windows.
oshell> fs.ls -r . | where .size > 10kb | sort-by .size --desc | take 5
Status: 0.0.1 (pre-alpha). Python 3.12+, standard library only.
The PyPI name is open-shell-ai (openshell and open-shell are taken). The
command you run is openshell.
pip install open-shell-ai
openshell --version
From this repo, without publishing:
python3 -m venv .venv
.venv/bin/pip install -e .
.venv/bin/openshell -c 'help'
# or: ./openshell.py -c 'help'
pip ships the core + basic commands. Extra and advanced commands are not
on PyPI — they live on the website registry.
Quick start
# Interactive shell
openshell
# One pipeline, then exit
openshell -c 'fs.ls'
openshell -c 'fs.ls -r . | where .size > 10kb | sort-by .size --desc | take 5'
openshell -c 'help | select .name .summary'
# Force NDJSON (also the default when stdout is not a TTY)
openshell --json -c 'fs.ls | select .name .size'
# Works inside bash / jq
openshell -c 'fs.ls | select .name .size' | jq .name
On a terminal, the last stage renders a table. When piped, it writes one JSON object per line (NDJSON).
How the pipeline works
Each command yields records. Only sinks (to json, to table) print.
| passes the record stream downstream. take 5 stops early, so
fs.ls -r /usr | take 3 does not walk the whole tree.
fs.ls -r . → {name, path, is_dir, size, modified} …
| where .size > 10kb
| sort-by .size --desc
| take 5
| select .name .size
| to table
Predicates use a leading dot for fields. Size units (10kb, 1mb) and
=~ (regex) are built in:
where .size > 10mb
where .name =~ "\.py$"
where .is_dir
Errors are records, never raw tracebacks:
{"$t": "error", "code": "cmd.not_found", "message": "…", "hint": "…"}
Basic commands (ship with pip)
| Command | Usage | What it does |
|---|---|---|
fs.ls |
fs.ls [PATH] [-r] [-a] |
List files as records |
where |
where .FIELD [OP VALUE] |
Filter (>, <, ==, !=, >=, <=, =~) |
select |
select .FIELD … |
Keep named fields |
sort-by |
sort-by .FIELD [--desc] |
Sort (buffers the stream) |
take |
take N |
First N records |
to |
to json|table [--compact] |
Render the stream |
help |
help [NAME] |
List loaded commands as records |
command |
command |
Same idea: every command as a record |
version |
version |
Version and runtime |
search |
search [QUERY] |
List extras on the website registry |
install |
install NAME |
Download an extra into ~/.config/oshell/command/ |
remove |
remove NAME |
Remove a website extra (not a built-in) |
help itself is a source command, so this works:
openshell -c 'help | select .name .usage .origin'
Website extras (not on PyPI)
Host the registry/ folder so this URL exists:
https://openshell.dev/registry/index.json
openshell -c 'search'
openshell -c 'install count'
openshell -c 'fs.ls | count'
openshell -c 'remove count'
Until the site is live, use the copy in this repo:
export OSHELL_REGISTRY_URL="file://$PWD/registry"
openshell -c 'search | to table'
openshell -c 'install uniq'
Current extras in registry/:
| Command | Usage | What it does |
|---|---|---|
count |
count |
Count incoming records |
uniq |
uniq [.FIELD] |
Drop consecutive duplicates |
install writes ~/.config/oshell/command/<file>.py and checks the sha256
in registry/index.json. Built-ins cannot be removed.
Writing a command
One file per command. Drop it in command/ (basic, ships with pip) or
registry/commands/ (website extra). The decorator is the name, not the
filename: sort_by.py registers sort-by.
from openshell import Records, command
@command("greet", "Say hello as a record", "greet [NAME]", source=True)
def greet(_input: Records, args: list[str]) -> Records:
yield {"hello": args[0] if args else "world"}
No registration step. Files starting with _ are skipped. A broken file is
reported and skipped; it does not kill the shell.
User-local commands (no install):
~/.config/oshell/command/my_cmd.py
Or any directory on $OSHELL_COMMAND_PATH (separated by os.pathsep).
Load order, later wins on a name clash:
<install>/oshell_command/*.py— basic set from pip~/.config/oshell/command/*.py— website extras and your files$OSHELL_COMMAND_PATH
CLI
openshell start the interactive shell
openshell -c PIPELINE run one pipeline and exit
openshell --json -c ... force NDJSON output
openshell --version
openshell --help
| Variable | Meaning |
|---|---|
OSHELL_REGISTRY_URL |
Catalog root (default https://openshell.dev/registry) |
OSHELL_COMMAND_PATH |
Extra command directories |
NO_COLOR |
Disable ANSI color |
Repository
openshell.py core: registry, loader, pipeline, REPL
command/ basic commands (shipped on PyPI)
registry/ website extras (not in the wheel)
index.json catalog + sha256
commands/*.py one extra command per file
skills/ design plan and build steps
image/ banner
The repo folder is command/. It installs as oshell_command/ so it does not
squat the name command in site-packages.
Publish
pip install build twine
rm -rf dist
python -m build
twine upload dist/open_shell_ai-*
Confirm extras stayed off the wheel:
unzip -l dist/open_shell_ai-*.whl | grep -E 'count|uniq|registry' || echo ok
Then upload registry/ to https://openshell.dev/registry.
License
Apache-2.0
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
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 open_shell_ai-0.0.1.tar.gz.
File metadata
- Download URL: open_shell_ai-0.0.1.tar.gz
- Upload date:
- Size: 21.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
421b1959ef8bc42a7dcceea5000ca59f93d102488828378f538621061289b842
|
|
| MD5 |
25b2a11eaa64006c7d1557004be8ef22
|
|
| BLAKE2b-256 |
55c035ac5eeaa2137b2157f3fcff3d24e5838af7b1bf1830bd19dfbbf9e9be5b
|
File details
Details for the file open_shell_ai-0.0.1-py3-none-any.whl.
File metadata
- Download URL: open_shell_ai-0.0.1-py3-none-any.whl
- Upload date:
- Size: 22.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26c277e0fc89c8a8aad8d54af7c56a48b0ab3b92aa20703b03514fa20eb4b991
|
|
| MD5 |
5de6825730f23e6e9e2b8ca36eeba618
|
|
| BLAKE2b-256 |
40b67e448269d7ea8915df4f94979d3ab774e26e3ea2e98e43e46c2d1d34a37e
|