A CLI tool to register and retrieve terminal commands using natural language and semantic search
Project description
cmdrun
Stop googling the same commands. Describe what you want in plain English — cmdrun finds it instantly and copies it to your clipboard.
$ cmdrun "show all pods"
kubectl get pods -A
Copied to clipboard.
Runs entirely offline. No data leaves your machine.
Table of contents
Installation
pip install cmdrun
Requires Python 3.9+.
Quick start
1. Register a command
$ cmdrun register
Register a new command
Description: list all kubernetes pods
Command: kubectl get pods -A
✓ Registered: 'list all kubernetes pods' → kubectl get pods -A
2. Find it with natural language
$ cmdrun "show pods"
kubectl get pods -A
Copied to clipboard.
The matched command is printed and automatically copied to your clipboard.
3. Execute it directly
$ cmdrun --run "show pods"
kubectl get pods -A
Copied to clipboard.
Running: kubectl get pods -A
...
Commands
| Command | Description |
|---|---|
cmdrun register |
Interactively save a new description → command pair |
cmdrun "query" |
Find the best-matching command and copy it to clipboard |
cmdrun --run "query" |
Find and immediately execute the best-matching command |
cmdrun list |
Show all saved commands in a table |
cmdrun remove |
Delete a saved command by its list index |
cmdrun clear |
Delete all saved commands |
cmdrun rebuild |
Rebuild the search index from commands.json |
Flags
| Flag | Description |
|---|---|
--run / -r |
Execute the matched command after displaying it |
--verbose / -v |
Enable debug-level logging |
How it works
cmdrun uses semantic search to match your natural language query against saved command descriptions — so "show pods", "list k8s containers", and "kubernetes running services" all find the same command.
Search pipeline
cmdrun "show all pods"
│
▼
daemon.py ← persistent background process, model loaded once
│
▼
embeddings.py — sentence-transformers/all-MiniLM-L6-v2 (384d, offline)
│
▼
vector_store.py — FAISS IndexFlatIP (cosine similarity)
│
▼
matcher.py — top-k search + threshold filtering
│
▼
storage.py — commands.json (source of truth)
Background daemon
On the first query, cmdrun starts a background daemon that loads the embedding model once and keeps it in memory. Every subsequent query connects to the daemon via a Unix socket — no model reloading, no cold-start delay.
The daemon exits automatically after 30 minutes of inactivity and restarts on the next query.
Similarity search
- Query text is embedded with
all-MiniLM-L6-v2(384 dimensions, L2-normalised). - FAISS
IndexFlatIPperforms an inner-product search (equivalent to cosine similarity for unit vectors). - The top-3 candidates are evaluated.
- If the best match scores below 0.60 cosine similarity, the result is rejected.
Data files — all stored in ~/.cmdrun/
| File | Purpose |
|---|---|
commands.json |
Human-readable list of saved description → command pairs |
index.faiss |
FAISS binary index |
metadata.pkl |
Maps FAISS positions back to CommandEntry objects |
daemon.sock |
Unix socket used by the background daemon |
Performance
| Operation | Latency |
|---|---|
| First query (daemon cold start) | ~1–2 s |
| Subsequent queries (daemon warm) | ~300–400 ms |
register (daemon warm) |
~300–400 ms |
The ~300–400 ms on warm queries is Python's own startup time. The model inference and FAISS lookup together take under 15 ms inside the daemon.
Configuration
Adjust constants in cmdrun/config.py:
| Constant | Default | Description |
|---|---|---|
SIMILARITY_THRESHOLD |
0.60 |
Minimum cosine similarity to accept a match |
TOP_K |
3 |
Number of candidates to evaluate per query |
EMBEDDING_MODEL |
sentence-transformers/all-MiniLM-L6-v2 |
HuggingFace model ID |
Development
# Install in editable mode with dev extras
pip install -e ".[dev]"
# Run tests
pytest
# Run tests with coverage
pytest --cov=cmdrun --cov-report=term-missing
# Lint
ruff check cmdrun tests
# Type-check
mypy cmdrun
Project layout
cmdrun/
├── cli.py Typer app — all user-facing commands
├── config.py Paths, model name, thresholds
├── daemon.py Background server — keeps model warm, handles queries
├── client.py Thin socket client used by cli.py
├── embeddings.py sentence-transformers wrapper (lazy-loaded, noise-suppressed)
├── storage.py commands.json read/write (Pydantic models)
├── vector_store.py FAISS index management
└── matcher.py High-level matching pipeline
tests/
└── test_matcher.py pytest suite (embeddings, vector store, matcher, storage)
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 cmdrun-0.1.1.tar.gz.
File metadata
- Download URL: cmdrun-0.1.1.tar.gz
- Upload date:
- Size: 16.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2da288139f21010f0cae6a9a3e06b10fa6d7dd5e43bf4ea7caeec7d685b0ae49
|
|
| MD5 |
165a3d1bc7db61f8ec399857e87a6863
|
|
| BLAKE2b-256 |
10d8d785784cef26a81a60106c42a19aeb619ed98d907a8cc0e839ed88571281
|
File details
Details for the file cmdrun-0.1.1-py3-none-any.whl.
File metadata
- Download URL: cmdrun-0.1.1-py3-none-any.whl
- Upload date:
- Size: 18.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c29b3c08ff6ea4b57ae86eb513152f8a829a90c9da2d5912341f2e00f1221b7
|
|
| MD5 |
4e2bbe4b95c162b05983ea38a1f0068d
|
|
| BLAKE2b-256 |
cb404f94dcd5cd02cce5a3d2338e8e40c3f94dca1d2892a99980d9d0fdc04b92
|