Skip to main content

Polycmd

Polycmd is a shared multi platform syntax, zero dependency python based, terminal that runs a practical subset of POSIX, Windows CMD, and PowerShell commands through one safe, portable Python execution model.

current_version = "v0.17.0"

Commands are compiled into canonical operations before execution. Supported commands are not forwarded to a native shell, keeping behavior consistent across Windows, macOS, and Linux.

Quick start

Install

pip install polycmd

Polycmd supports Python 3.11, 3.12, and 3.13.

Open the lightweight terminal

polycmd terminal

The standard-library Tkinter terminal accepts commands without a polycmd prefix:

ls -la
dir /s /b *.py
Get-ChildItem . -Force
cat app.log | grep error > errors.txt

It keeps one Polycmd session alive, including its virtual working directory and command history. The dialect selector appears on the left of the command path and offers Auto, POSIX, CMD, and PowerShell; Auto is selected by default. Enter runs a command, Up and Down navigate history, Ctrl+L clears the display, and Ctrl+Q exits.

Wildcard directory listings are expanded inside Polycmd rather than by the host shell, so they behave consistently in the terminal on every platform:

ls *.md*
dir /s /b *.py
Get-ChildItem docs/*.md

Tkinter is included with standard CPython installers for Windows and macOS. Some minimal Linux distributions package Tk separately.

Get help

Display catalog-backed help from the command line:

polycmd --help
polycmd help ls
polycmd ls --help
polycmd help fs.copy

Use the same forms inside the lightweight terminal without a polycmd prefix:

help
help ls
ls --help
help dir
help Get-ChildItem
help fs.copy

Help is generated from the live command and operation catalogs. It includes plugin commands, resolves aliases, and shows every dialect when a name has more than one meaning. Command providers can supply a description, usage syntax, and examples; otherwise Polycmd uses the compiler function's docstring.

Why Polycmd?

Applications frequently need command-like behavior without depending on the host operating system's shell syntax, quoting rules, or installed utilities. Polycmd separates command syntax from execution:

POSIX / CMD / PowerShell command
              ↓
       Dialect strategy
              ↓
       Canonical Polycmd IR
              ↓
       Registered operation
              ↓
       Portable Python service

This provides:

  • one API for POSIX, CMD, and PowerShell input;
  • conservative automatic dialect detection;
  • portable filesystem, text, and environment operations;
  • composable pipelines, redirects, conditionals, and sequences;
  • filesystem confinement and explicit destructive-operation metadata;
  • disabled-by-default external process execution;
  • open registries for third-party dialects, commands, and operations;
  • catalog-driven serialization and capability discovery.

Polycmd is a compatibility runtime, not a complete Bash, CMD, or PowerShell emulator. Unsupported syntax fails explicitly.

Command-line usage

Run a command using automatic dialect detection:

polycmd "ls -la ./data"
polycmd "dir /s /b *.py"
polycmd "Get-ChildItem ./data -Force"

Compile a command into canonical JSON without executing it:

polycmd compile --dialect posix "cat app.log | grep error > errors.txt"

Execute a previously serialized program:

polycmd execute program.json

Inspect installed capabilities:

polycmd capabilities

Python API

from pathlib import Path

from polycmd import Shell, ShellConfig


shell = Shell(
    ShellConfig(
        root=Path("./workspace"),
        discover_plugins=False,
    )
)

result = shell.run("Get-ChildItem . -Force")
print(result.stdout)

Select a dialect explicitly when required:

program = shell.compile(
    "cat app.log | grep error > errors.txt",
    dialect="posix",
)

result = shell.execute(program)

Serialize and replay the same canonical program:

payload = shell.serialization.dumps(program)
restored = shell.serialization.loads(payload)

assert restored == program
shell.execute(restored)

Supported command surface

Capability Examples
Filesystem list, current directory, change directory, create, copy, move, delete, touch, find
Text read, write, search, head, tail, sort, unique, count
Environment list and retrieve variables
Composition pipelines, >, >>, ;, &&, `
Program data canonical JSON serialization and replay
Dialects POSIX, CMD, PowerShell, and registered third-party dialects

For example, these commands compile to equivalent canonical operations:

cat app.log
type app.log
Get-Content app.log

Shell integration

Polycmd can expose registered operation and dialect command names through the normal system PATH:

polycmd shell install
polycmd shell status
polycmd shell uninstall

Restart the terminal after installation. On Zsh, Polycmd installs managed noglob aliases so foreign-dialect wildcard syntax reaches Polycmd unchanged:

dir /s /b *.py

Commands without a registered Polycmd shim continue through the native PATH. When an entire compound expression must be compiled by Polycmd, use the Tkinter terminal or the explicit polycmd "..." form. Otherwise, operators such as | and > remain owned by the active host shell.

Configuration and security

Relative paths are confined beneath ShellConfig.root. Polycmd maintains a virtual current directory and never changes the host process directory with os.chdir().

External process execution is disabled by default. Enabling it requires both allow_external=True and an exact executable name in external_allowlist:

from pathlib import Path

from polycmd import Shell, ShellConfig


shell = Shell(
    ShellConfig(
        root=Path("./workspace"),
        allow_external=True,
        external_allowlist=("python",),
    )
)

External arguments are passed as an array with shell=False. Polycmd does not fall back to executing unsupported input through a native shell.

Extending Polycmd

Add or replace a dialect command

from polycmd import CommandDefinition
from polycmd.ir import WriteText


def compile_hello(invocation):
    return WriteText(text=" ".join(invocation.argv))


shell.register_command(
    "posix",
    CommandDefinition("hello", compile_hello),
)

Existing names are protected unless replace=True is explicitly supplied.

Add an operation

from dataclasses import dataclass

from polycmd.ir import Operation
from polycmd.registries import OperationDefinition


@dataclass(frozen=True, kw_only=True)
class CompressArchive(Operation):
    source: str
    destination: str


context.operations.register(
    OperationDefinition(
        operation_id="archive.compress",
        operation_type=CompressArchive,
        handler=compress_archive,
        shell_aliases=("compress",),
    )
)

The operation catalog owns execution, serialization identity, destructive metadata, capabilities, and shell names. Plugins can register through the polycmd.plugins entry-point group without changing Polycmd core.

More detail is available in:

Development

Clone the repository and install the development environment:

git clone https://github.com/systemizing-solutions/polycmd.git
cd polycmd
poetry install

Run the quality gates:

poetry run pytest
poetry run ruff check src/polycmd tests
poetry run ruff format --check src/polycmd tests
poetry run mypy

BumpVer

Preview a version change before applying it:

poetry run bumpver update --patch --dry
poetry run bumpver update --minor --dry
poetry run bumpver update --major --dry

Apply a release bump:

poetry run bumpver update --patch

BumpVer updates pyproject.toml, src/polycmd/__init__.py, and this README, creates the version commit and tag, and pushes them. Pushing a semantic version tag starts the PyPI publication workflow.

Build locally

poetry check
poetry build

The build produces a source distribution and a universal Python wheel in dist/.

Automated PyPI publishing

The publish.yml workflow publishes semantic version tags through PyPI trusted publishing. No PyPI API token is stored in GitHub.

One-time repository setup:

  1. Create the polycmd project or a pending trusted publisher on PyPI.
  2. Set the GitHub owner to systemizing-solutions.
  3. Set the repository to polycmd.
  4. Set the workflow filename to publish.yml.
  5. Set the environment name to pypi.
  6. Create a matching GitHub environment named pypi.

For every tagged release, GitHub Actions verifies that the tag equals the Poetry version, validates package metadata, runs linting, typing, and tests, builds both distribution formats, and publishes them using OpenID Connect.

License

Polycmd is released under the MIT License. See LICENSE.

Credits

Author: Ryan Julyan

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

polycmd-0.17.0.tar.gz (45.8 kB view details)

Uploaded Source

Built Distribution

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

polycmd-0.17.0-py3-none-any.whl (68.4 kB view details)

Uploaded Python 3

File details

Details for the file polycmd-0.17.0.tar.gz.

File metadata

  • Download URL: polycmd-0.17.0.tar.gz
  • Upload date:
  • Size: 45.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.2 CPython/3.12.2 Windows/11

File hashes

Hashes for polycmd-0.17.0.tar.gz
Algorithm Hash digest
SHA256 a6c5d8b97e80262503d111d4a41d6f4ecac4ed1656157db0c1b34de897873940
MD5 637ae56ab1de03c71ea4c6fb10533286
BLAKE2b-256 39b445725da2917395bdabe766a38048fa5eefe7e45e9671893a5d70729524b1

See more details on using hashes here.

File details

Details for the file polycmd-0.17.0-py3-none-any.whl.

File metadata

  • Download URL: polycmd-0.17.0-py3-none-any.whl
  • Upload date:
  • Size: 68.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.2 CPython/3.12.2 Windows/11

File hashes

Hashes for polycmd-0.17.0-py3-none-any.whl
Algorithm Hash digest
SHA256 188ad6abf9483ca4706277750bbfdfc25fd0d4ddf6931156f7e381f58bb71174
MD5 6f7335807cebbf4c9c7275e5cb724578
BLAKE2b-256 9e606e06e267ddaa5705904cf3f1aacf743fd331b216b2dadfbc176c134438b6

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.17.0 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