Skip to main content

Turn natural language into shell commands via the DeepSeek API, with a confirm-before-run step.

Project description

nlsh

Describe what you want to do in plain language; nlsh asks the DeepSeek API for the matching shell command, shows it with a short explanation, and waits for your confirmation before running it.

$ nlsh find the 5 largest files under this directory
╭─ proposed command ───────────────────────────────────────╮
│ $ du -ah . | sort -rh | head -n 5                         │
│                                                           │
│ Lists files by size and shows the five largest.          │
╰───────────────────────────────────────────────────────────╯
Run it? [y/n/e] (n):

y runs it, n cancels, e opens the command in your $EDITOR first.

Install

Once published to PyPI, install it as a standalone tool (the package is nlsh-cli; the command it installs is nlsh):

uv tool install nlsh-cli     # or: pipx install nlsh-cli

From source

One command sets up the virtual environment and all dependencies from the lockfile:

uv sync

This creates .venv/ and installs nlsh. Run it with uv run nlsh ..., or activate the env first (source .venv/bin/activate) and just call nlsh.

Plain pip (no uv) works too:

python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
pip install -e .

Configure

Easiest — store the key interactively (written to ~/.config/nlsh/config.toml, mode 0600):

nlsh config set-key
nlsh config set-model deepseek-v4-pro   # optional, change default model
nlsh config show                        # show resolved config (key masked)

Or via environment variable:

export DEEPSEEK_API_KEY=sk-...

or edit ~/.config/nlsh/config.toml directly:

api_key  = "sk-..."
model    = "deepseek-v4-flash"        # optional (also: deepseek-v4-pro)
base_url = "https://api.deepseek.com" # optional

Resolution order for each setting is: environment variable → config file → default.

Usage

nlsh <natural language request>

  -y, --yes        run without confirmation (dangerous commands still prompt)
  -n, --dry-run    only print the command, never run it
      --pro        use the stronger model (deepseek-v4-pro) for this request
  -m, --model ID   override the model id for this request
      --version    show version

At the confirmation prompt: y runs, n cancels, e edits first. Commands that match risky patterns (rm -rf, dd of=/dev/…, mkfs, fork bombs, curl … | sh, sudo, …) are flagged in red and require typing the full word yes before they run — even under --yes. Multi-stage commands (pipes, &&) are shown with a per-step breakdown.

Development

uv sync                 # installs deps + dev tools (pytest, ruff)
uv run pytest -q        # run the test suite
uv run ruff check .     # lint

CI (GitHub Actions) runs ruff + pytest across Python 3.9–3.13 and checks the lockfile on every push and PR.

Releasing

The version is derived from the git tag by hatch-vcs, so a release is just a tag:

git tag v0.1.0
git push origin v0.1.0

The Publish workflow builds the sdist/wheel and uploads them to PyPI via Trusted Publishing (configure a pypi environment on the repo and register the workflow as a trusted publisher — no API token stored).

How it works

nlsh sends your request plus context (OS, shell, current directory) to the DeepSeek chat API constrained to JSON output, parses {command, explanation}, and runs the chosen command through your $SHELL so aliases and the working directory behave as expected.

Project details


Download files

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

Source Distribution

nlsh_cli-0.1.0.tar.gz (27.9 kB view details)

Uploaded Source

Built Distribution

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

nlsh_cli-0.1.0-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file nlsh_cli-0.1.0.tar.gz.

File metadata

  • Download URL: nlsh_cli-0.1.0.tar.gz
  • Upload date:
  • Size: 27.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for nlsh_cli-0.1.0.tar.gz
Algorithm Hash digest
SHA256 de8a1b5a0ade101cabf0abd964f6a698318ca239f208414167f68582a5a7c47d
MD5 02fce70011c7bb7495baed5c1581227f
BLAKE2b-256 fd1f79a7d9e2794cb4401b530e4fe521795d4686d3149dc1f9c8761a52003aa8

See more details on using hashes here.

File details

Details for the file nlsh_cli-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: nlsh_cli-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for nlsh_cli-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d97e7e838212fb8bac48d00679d35675fdbc6b990a0a0d6464922f39ac750825
MD5 70823673a51b54231a00a881134da524
BLAKE2b-256 7d11967fb84ec68494bd69765fbebf649e35685743afaa1c651ae7fa14405f3f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page