Skip to main content

Open Shell

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:

  1. <install>/oshell_command/*.py — basic set from pip
  2. ~/.config/oshell/command/*.py — website extras and your files
  3. $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

open_shell_ai-0.0.1.tar.gz (21.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

open_shell_ai-0.0.1-py3-none-any.whl (22.0 kB view details)

Uploaded Python 3

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

Hashes for open_shell_ai-0.0.1.tar.gz
Algorithm Hash digest
SHA256 421b1959ef8bc42a7dcceea5000ca59f93d102488828378f538621061289b842
MD5 25b2a11eaa64006c7d1557004be8ef22
BLAKE2b-256 55c035ac5eeaa2137b2157f3fcff3d24e5838af7b1bf1830bd19dfbbf9e9be5b

See more details on using hashes here.

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

Hashes for open_shell_ai-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 26c277e0fc89c8a8aad8d54af7c56a48b0ab3b92aa20703b03514fa20eb4b991
MD5 5de6825730f23e6e9e2b8ca36eeba618
BLAKE2b-256 40b67e448269d7ea8915df4f94979d3ab774e26e3ea2e98e43e46c2d1d34a37e

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page