Local AI-powered terminal assistant with explicit confirmation and safety controls
Project description
OTerminus
OTerminus is a local, safety-first terminal assistant. It turns natural-language requests into a single proposed shell action, shows a preview, and by default executes only after explicit confirmation.
Why OTerminus exists
Terminal copilots are useful, but unrestricted shell generation is risky. OTerminus exists to provide a practical middle ground:
- capability-first command support (curated workflows, not full shell emulation)
- deterministic rendering for structured command families
- explicit policy + validation gates before execution
- confirmation before execution by default, with an opt-in narrow exception for validated local read-only structured commands
- local-first observability through JSONL audit logs
Core safety promise
OTerminus is designed around an inspect-and-confirm execution contract:
- detect direct commands first
- intercept vague natural-language requests as ambiguous when needed
- route specific natural-language requests by capability
- plan proposals in a structured-first format
- validate and policy-check the command
- show a deterministic preview
- require explicit user confirmation before execution by default
Direct shell commands are not blocked by natural-language ambiguity heuristics; they still go through validation and policy checks. Ambiguous natural-language requests stop before planning and execution and suggest safer read-only inspections. See the user guide and request lifecycle for details.
If ambiguity handling, validation, or policy checks block a request, OTerminus does not execute.
Users may explicitly enable a narrowly constrained safe auto-execute policy for validated, warning-free, local read-only structured commands:
export OTERMINUS_AUTO_EXECUTE_SAFE=true
Alternatively, put OTERMINUS_AUTO_EXECUTE_SAFE=true in a .env file in the directory where you
start OTerminus. Exported shell variables override .env values.
The preview, validator, and policy checks still run first. Only direct-command detection and the deterministic local planner can qualify. Network commands, warnings, write/dangerous risk, experimental proposals, Ollama-planned proposals, project-health commands, archive extraction or creation, and history reruns still require confirmation.
Quick install and setup
Requirements
- Python 3.13+
- macOS or a Unix-like POSIX terminal environment with the required shell commands available
- Ollama for natural-language planning
- pipx for isolated end-user installs
- Poetry for local development
Supported platforms
OTerminus currently targets macOS and Unix-like terminal environments. The command registry contains
platform-aware packs: macOS desktop commands such as open are available only on supported macOS
(darwin) systems, hidden from suggestions and planner context where practical elsewhere, and still
rejected by the validator before execution if requested on an unsupported platform.
Linux-like environments may work when the required shell commands and Ollama are installed, but
OTerminus does not yet claim native Windows Command Prompt or PowerShell support. Windows users
should run OTerminus inside WSL for a Unix-like shell boundary; no Windows command support is added
or implied. Run oterminus doctor after installation to see the detected platform and readiness
checks.
Install from PyPI
Released OTerminus packages are published as oterminus and expose the oterminus and
oterminus-evals console scripts. For normal CLI use, prefer pipx because it isolates OTerminus
and its dependencies from your system Python environment:
pipx install oterminus
oterminus --version
oterminus doctor
oterminus
Use oterminus --version after install or upgrade to confirm the installed package version. Use
oterminus doctor after installation to check the package/runtime environment, pipx or virtualenv
context, platform, configuration files, audit/history paths, and Ollama readiness before your first
natural-language planning request. PyPI installation does not install or start an Ollama model for
you. Direct commands and some deterministic local paths may not need a live model, but first-run
natural-language usage depends on Ollama being installed, running, and having a local model
available.
On the first bare interactive launch (oterminus) with no existing user config file, OTerminus
offers a concise configuration wizard. The wizard sets safety/privacy defaults and can select an
installed Ollama model, but model selection is optional and direct commands remain usable without
Ollama. One-shot requests such as oterminus "ls -l", --dry-run, --explain, doctor,
version, completion, and config commands do not trigger onboarding.
Upgrade or uninstall the isolated CLI with:
pipx upgrade oterminus
pipx uninstall oterminus
If you cannot use pipx, install with pip instead:
python -m pip install oterminus
Shell completion vs. REPL autocomplete
OTerminus provides REPL Tab autocomplete through prompt_toolkit after you start the
interactive app with oterminus. It can also print opt-in shell-level completion scripts for the
outer command:
oterminus completion zsh
oterminus completion bash
oterminus completion fish
The completion command only prints the script to stdout; it never edits your .zshrc, .bashrc,
config.fish, or other shell startup files automatically. See the
shell completion docs for manual setup details.
Configuration management
Use the oterminus config namespace to inspect and manage local preferences:
oterminus config
oterminus config path
oterminus config show
oterminus config init
oterminus config init --defaults
oterminus config validate
oterminus config edit
These commands do not require Ollama and bypass request planning, validation, execution, audit, and
history. oterminus config path prints the active JSON config path selected by
OTERMINUS_CONFIG_PATH, current-directory .env, or the default ~/.oterminus/config.json.
oterminus config init runs the interactive onboarding wizard when stdin is a TTY. Use
oterminus config init --defaults for non-interactive safe defaults, and
oterminus config init --defaults --force to replace an existing valid file. config edit uses
$VISUAL, then $EDITOR, and never modifies shell startup files. The namespace is intentionally
oterminus config, not oterminus --config, so --config remains available for a future
alternate-path option.
Terminal color policy is configurable with OTERMINUS_COLOR=auto|always|never or persisted
color_mode:
export OTERMINUS_COLOR=auto
export OTERMINUS_COLOR=always
export OTERMINUS_COLOR=never
NO_COLOR=1 oterminus
Colors are semantic and supplementary: previews, diagnostics, discovery/help output, lifecycle
messages, and the REPL prompt keep visible labels even without color. auto disables styling when
output is redirected, and NO_COLOR disables ANSI styling at render time. Command stdout/stderr,
version output, shell completion scripts, config path, audit/history records, and JSON or other
machine-oriented output remain plain.
Local development install
poetry install
poetry run oterminus
Quick start examples
Common commands
oterminus
oterminus "show disk usage for this folder"
oterminus --dry-run "copy notes.txt to backup/notes.txt"
oterminus --explain "find processes matching python"
oterminus doctor
oterminus config show
Interactive REPL
oterminus starts the interactive REPL. On a first interactive launch without a config file it may
offer onboarding first, then reload the saved config before creating REPL services. Ollama setup is
lazy: it is needed only when a request reaches model-based planning or failure explanation. Use
poetry run oterminus when working from a local development checkout.
Examples inside REPL:
find all .py filescapabilities/commands/exampleshelp capabilities/help filesystem_inspection/help lsshow running processesping example.com 4 timesshow HTTP headers for https://example.comlook up DNS for example.comtar -tf archive.tar/unzip -l archive.ziptar -xf archive.tar -C restored/unzip archive.zip -d restoredtar -czf backup.tar.gz src/zip -r docs.zip docsls -lahdry-run search TODO in srcexplain show disk spaceaudit status/audit tail/audit clear
One-shot and diagnostics modes
- One-shot requests such as
oterminus "show disk usage for this folder"plan, validate, preview, and then require confirmation before execution unless the explicit safe auto-execute environment setting is enabled and the validated proposal qualifies. --dry-runand--explainare mutually exclusive one-shot inspection flags for requests. Both validate and preview without confirmation or execution; explain mode also describes command choice, relevant flags/arguments, risk, and policy interpretation.--versionprints the installed package version and exits. It does not start the REPL, run doctor/setup checks, or require Ollama;oterminus versionprints the same diagnostic output.doctoris diagnostics-only: it prints readiness checks and exits without starting the REPL, executing a request, or invoking the Ollama planner. It cannot be combined with--dry-runor--explain.
Proposal modes
OTerminus supports two first-class proposal modes:
- Structured: the preferred normal path for supported capabilities. Proposals use
command_family+ typedarguments, and Python renders the final command/argv deterministically. - Experimental: a constrained fallback for single-command text that cannot yet be represented safely as structured arguments. It is still strictly validated, previewed, and confirmed before execution.
Capability maturity/status comes from registry metadata. Planned or metadata-only capabilities are shown in detailed references/help with warnings, but are not advertised as normal executable autocomplete or planner actions until their maturity metadata is updated.
See structured rendering, routing and planning, and the request lifecycle for details.
Network diagnostics
The network_diagnostics capability supports only fixed-count ping, HTTP HEAD (curl -I), dig,
and nslookup. These commands contact external hosts, show a network metadata warning in preview,
and still require confirmation. OTerminus does not support POST/PUT/DELETE requests, secret headers,
downloads, scanning, SSH, or arbitrary network automation.
Project health
The project_health capability supports curated developer checks through structured operations:
tests, lint checks, format checks, docs builds, and evals. These render to exact poetry run ...
commands, may execute local project code, and always go through preview, validation, policy, and
confirmation. OTerminus does not support arbitrary Poetry commands, installs/updates,
deploy/publish commands, or write-formatting such as ruff format ..
Documentation
The README is the landing page. Full documentation is generated from docs/ and
published to GitHub Pages after merges to main (once Pages is enabled in repository settings).
- Hosted docs (after enablement):
https://pooriat.github.io/oterminus/ - Docs source of truth:
docs/ - Architecture overview:
docs/architecture/overview.md - Request lifecycle (central flow):
docs/architecture/request-lifecycle.md - User guide:
docs/product/user-guide.md - Configuration reference:
docs/reference/config.md - Contributor workflow:
docs/contributing.md - Changelog:
CHANGELOG.md - Release process:
docs/release.md - Contributor command-family guide:
docs/adding-command-families.md - Evals docs:
docs/architecture/evals.md
Work on docs locally
poetry install --with dev,docs
poetry run mkdocs serve
poetry run mkdocs build --strict
For the full local quality checklist, including Ruff format/lint and pytest commands, see the contributor workflow. When behavior changes, update docs in the same pull request.
- Optional local persistent REPL history is available via
OTERMINUS_HISTORY_ENABLED=true; reruns still go through normal validation + confirmation. - Audit logs and persistent history are local JSONL files; redaction is enabled by default, but review logs/history before sharing. See the audit schema and configuration reference.
For a small set of deterministic natural-language requests, OTerminus can skip Ollama by producing a local structured proposal before normal validation and confirmation policy.
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 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 oterminus-0.1.3.tar.gz.
File metadata
- Download URL: oterminus-0.1.3.tar.gz
- Upload date:
- Size: 102.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
441a98d1da7948081d43b98e237491fa9d25dc638c20197a95ef3d5d7018e559
|
|
| MD5 |
280cb24e89b1c9a6723a517658af4eb3
|
|
| BLAKE2b-256 |
0c59b1227dc92c907001329a714800c589b7cf7be837777e8223fd3862d4c964
|
Provenance
The following attestation bundles were made for oterminus-0.1.3.tar.gz:
Publisher:
publish-pypi.yml on PooriaT/oterminus
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oterminus-0.1.3.tar.gz -
Subject digest:
441a98d1da7948081d43b98e237491fa9d25dc638c20197a95ef3d5d7018e559 - Sigstore transparency entry: 1750639465
- Sigstore integration time:
-
Permalink:
PooriaT/oterminus@f81049a20b77c82751952aa02412d1312905f9ac -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/PooriaT
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@f81049a20b77c82751952aa02412d1312905f9ac -
Trigger Event:
push
-
Statement type:
File details
Details for the file oterminus-0.1.3-py3-none-any.whl.
File metadata
- Download URL: oterminus-0.1.3-py3-none-any.whl
- Upload date:
- Size: 124.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ca6b71f8c13622c0604d881f1a8f7f74cb2219746763ea2f6d613839043373a
|
|
| MD5 |
00d162b2ba6d00b7c6ca01890e844854
|
|
| BLAKE2b-256 |
0e18f31cbd53f7c2225c24e4c83a19917717b2357235e264df2677fcdfa42c7d
|
Provenance
The following attestation bundles were made for oterminus-0.1.3-py3-none-any.whl:
Publisher:
publish-pypi.yml on PooriaT/oterminus
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oterminus-0.1.3-py3-none-any.whl -
Subject digest:
7ca6b71f8c13622c0604d881f1a8f7f74cb2219746763ea2f6d613839043373a - Sigstore transparency entry: 1750639550
- Sigstore integration time:
-
Permalink:
PooriaT/oterminus@f81049a20b77c82751952aa02412d1312905f9ac -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/PooriaT
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@f81049a20b77c82751952aa02412d1312905f9ac -
Trigger Event:
push
-
Statement type: