Skip to main content

aiscript

PyPI version Python versions

Describe what you want in plain English and aiscript asks an LLM to write a script, caches it, and runs it. The model picks the language: your native shell (Bash on Linux/macOS, PowerShell on Windows) or Python when that fits better. Python scripts that need third-party packages get their own virtual environment. The next run is instant: no network, no config. Before anything risky is saved or run, every generated script is checked by a built-in static scan and, optionally, by a decision model: Jev by TypeSafe AI (hosted), OpenAI Decisions, or a local model served by Ollaya. Risky scripts are shown to you and need an explicit [y/N] approval.

Install

uv tool install aiscript
# or
pipx install aiscript
# or
pip install aiscript

Requires Python 3.10+.

To upgrade to the latest version, use the same tool you installed with:

uv tool upgrade aiscript
# or
pipx upgrade aiscript
# or
pip install --upgrade aiscript

Your config, prompts and cached scripts in ~/.config/aiscript/ are kept. To work on aiscript itself, see docs/development.md.

Quickstart

aiscript --init        # creates ~/.config/aiscript/config.yaml

Put your OpenAI and Jev API keys in ~/.config/aiscript/config.yaml (or export OPENAI_API_KEY and TYPESAFE_API_KEY). The same file is where you pick the models: the one that writes the scripts (default_provider) and the decision model that reviews them (reviewer_provider). For a local, keyless review, use Ollaya instead of Jev (see below). Jev keys come from https://console.typesafe.ai/keys.

Environment variables are the alternative to keys in the file:

export OPENAI_API_KEY=...
export TYPESAFE_API_KEY=...

Then run your first command:

aiscript sizes                       # first run: asks "What should 'sizes' do?"
aiscript sizes ~/Downloads --top 5   # later runs: cached, arguments passed straight through

Everything after the command name is passed untouched to the script (including --help). aiscript messages go to stderr; stdout belongs to the script, and the exit code is the script's.

Safety review / decision models

Every generated script is reviewed before it is saved:

  • A static regex scan (always on) flags privilege escalation, recursive or system-wide file changes, networking/firewall changes and remote code execution (curl | sh, iex).
  • A decision model (reviewer_provider) gives a second opinion: Jev (hosted; key from https://console.typesafe.ai/keys), OpenAI Decisions (see below), or Ollaya (local and keyless; set reviewer_provider: ollaya, default model jevk5:4b on localhost:11435; see https://ollaya.dev). Comment reviewer_provider out to use only the static scan.

If either check flags the script, you see the reasons and the code and must answer [y/N]; declining saves nothing. The review fails closed: if the reviewer errors or is unreachable, the script is treated as risky. With a non-interactive stdin, risky scripts are refused. This is a best-effort safety net, not a sandbox: read what you approve. Details: docs/safety.md.

Configuration

aiscript --init writes this starter ~/.config/aiscript/config.yaml (mode 600; keep it out of git):

# aiscript config. Contains API keys: keep it private (chmod 600) and out of git.
# Keys can also come from the environment: OPENAI_API_KEY, OPENAI_DECISIONS_API_KEY,
# TYPESAFE_API_KEY, <PROVIDER>_API_KEY.

# Provider that writes the scripts (override with $AISCRIPT_PROVIDER).
default_provider: openai

# Decision model that reviews scripts on top of the built-in static scan.
# Use `ollaya` for a local, keyless review; comment out to use only the static scan.
reviewer_provider: jev

providers:
  # OpenAI (or any OpenAI-compatible API). API key: https://platform.openai.com/api-keys
  openai:
    api_key: "..."
    model: "gpt-6-luna"
    # reasoning_effort: low    # none | low | medium | high | xhigh | max (model-dependent)

  # OpenAI Decisions API reviewer provider.
  # openai_decisions:
  #   kind: openai
  #   api: decisions
  #   api_key: "..."
  #   model: "gpt-6-luna"

  # Jev (TypeSafe AI) safety reviewer. API key: https://console.typesafe.ai/keys
  jev:
    api_key: "..."

  # Uses Ollaya for a local decision model (https://ollaya.dev), model example: jevk5:4b
  # ollaya:
  #   model: "jevk5:4b"

  # Uses Ollama for a local LLM to create the scripts (set `default_provider: ollama`)
  # ollama:
  #   base_url: "http://localhost:11434/v1"
  #   model: "qwen3"

Placeholder keys ("...") are ignored, so if you leave them, the environment variables above work as-is. All options (provider kinds, api, temperature, key and model resolution, every environment variable, the legacy secrets.yaml): docs/configuration.md.

OpenAI Decisions reviewer

To use OpenAI Decisions instead of Jev, select reviewer_provider: openai_decisions and uncomment the corresponding provider block above. Supply its own api_key, or export OPENAI_DECISIONS_API_KEY; this named reviewer does not fall back to OPENAI_API_KEY. The default model is gpt-6-luna, and model remains configurable for future models.

Decisions uses the official OpenAI endpoint only. One request checks the same four hazards, flagging probabilities >= 0.5. Requests use a 30-second transport timeout with zero retries. Errors, refusals and malformed answers require the existing risk confirmation; they are refused in noninteractive builds. Static findings and dependency warnings always remain effective.

Existing reviewers and cached scripts keep working. To roll back, restore your previous reviewer_provider before downgrading aiscript. See configuration and safety for the full contract.

Usage

Command Action
aiscript NAME [args...] Run a command; created and built on first use
aiscript --init Create config dirs and a config.yaml template (never overwrites)
aiscript --list Table of commands, descriptions and usage (* = prompt changed, will rebuild)
aiscript --edit NAME Open the prompt in $VISUAL / $EDITOR (fallback nano/vi, notepad on Windows)
aiscript --rebuild NAME Regenerate the script and print its path; does not run it
aiscript --remove NAME Delete the command's prompt and cached script
aiscript --help, --version Help / version

Command names must match [A-Za-z0-9][A-Za-z0-9_-]*.

Shell or Python

The model is told your OS, architecture, native shell, the Python version it will run under and whether uv is installed, and chooses the language: the shell for thin wrappers around CLI tools and pipelines, Python for parsing JSON/CSV/HTML, data processing, HTTP APIs and anything that would be fragile in shell. Say "in python" or "as a shell script" in your description to ask for one; the model follows it unless it is clearly a poor fit (and then notes why in the script header). aiscript --list shows each command's language.

  • Standard-library Python is saved as functions/NAME.py and run with the system python3 (py -3 on Windows), or with aiscript's own interpreter if there is none.
  • Python with dependencies declares them in an inline PEP 723 block. After you approve (any dependency requires a [y/N] approval that lists the packages), aiscript creates functions/NAME/ with main.py and a private .venv: with uv (pyproject.toml + uv.lock, uv sync) or otherwise with python -m venv + pip install -r requirements.txt. The script always runs with that venv's interpreter, so later runs are offline. A rebuild with the same dependencies reuses the venv; a failed install keeps the previous version. Without uv, Debian/Ubuntu need python3-venv.

How it works

~/.config/aiscript/          # or $XDG_CONFIG_HOME/aiscript, or $AISCRIPT_HOME
├── config.yaml              # providers and keys
├── prompts/<name>.txt       # your intent for each command
└── functions/
    ├── <name>.sh            # generated, reviewed scripts (.ps1 on Windows)
    ├── <name>.py            # standard-library Python
    └── <name>/              # Python with dependencies
        ├── main.py
        ├── .venv/
        └── pyproject.toml + uv.lock  (or requirements.txt)

The first run of NAME saves your description to prompts/NAME.txt, asks the LLM for a script, reviews it, and stores it in functions/ (only one build per command: switching language replaces the old one). Later runs just execute the cached script. If the prompt is newer than the script (after --edit or a manual change), the script is rebuilt on the next run. A --rebuild that fails or is rejected keeps the previous script.

Docs

Metadata

Release files for aiscript 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aiscript 1.2.0
File Size Uploaded Provenance Actions
aiscript-1.2.0.tar.gz 38.9 kB With provenance Details for aiscript-1.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for aiscript 1.2.0
File Interpreter ABI Platform Actions
aiscript-1.2.0-py3-none-any.whl Python 3 none any Details for aiscript-1.2.0-py3-none-any.whl

Total release size: 83.3 kB

Release files / aiscript-1.2.0.tar.gz

Download URL aiscript-1.2.0.tar.gz
Size 38.9 kB
Tags Source
SHA-256 checksum
How to use checksums
519b4cbc3634e28521ef5b6746ed42a2109f7aad9f2593b1734fa62c0aa79ccb
BLAKE2b-256 checksum
How to use checksums
0ef237b554949c08039753698b9675366e999472cd7a38bcb1316208dce88806
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / aiscript-1.2.0-py3-none-any.whl

Download URL aiscript-1.2.0-py3-none-any.whl
Size 44.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3321c005ac2319da3268489be7756579202a79c4eefe87a69936420d50c31c7a
BLAKE2b-256 checksum
How to use checksums
059d215041ec4b5b9f0fd2b45297e4daf9d86aa41ba410bc5baa3ec7afa9a315
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Security for aiscript 1.2.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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for aiscript-1.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

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.

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