Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

 ██████╗███╗   ███╗██████╗
██╔════╝████╗ ████║██╔══██╗
██║     ██╔████╔██║██║  ██║
██║     ██║╚██╔╝██║██║  ██║
╚██████╗██║ ╚═╝ ██║██████╔╝
 ╚═════╝╚═╝     ╚═╝╚═════╝
Your words become commands.
$ cmd
┌────────────────────────────────────────────────────────────┐
│  $ cmd find files larger than 100MB                        │
│                                                            │
│  ╭──────────────────────────────────────────────────────╮  │
│  │ find . -size +100M -type f                           │  │
│  ╰──────────────────────────────────────────────────────╯  │
│    ↳ copied to clipboard                                   │
│    ↳ use --enable-execution to run this command            │
└────────────────────────────────────────────────────────────┘

You know what you want. You just forgot the syntax. We all do.


Why cmd?

┌─────────────────────┬──────────────────────────────────────┐
│ ▸ Natural Language  │ Describe what you want in English    │
├─────────────────────┼──────────────────────────────────────┤
│ ▸ Multi-Provider    │ Claude, OpenAI, Ollama, Azure, Groq  │
├─────────────────────┼──────────────────────────────────────┤
│ ▸ Secure by Default │ Keychain storage, no plain text      │
├─────────────────────┼──────────────────────────────────────┤
│ ▸ Safe by Default   │ Dry-run mode, destructive guard      │
├─────────────────────┼──────────────────────────────────────┤
│ ▸ Single Binary     │ No Python, no Node, just Rust        │
└─────────────────────┴──────────────────────────────────────┘

Quick Start

Installation

# Clone and build
git clone https://github.com/Proteusiq/cmd.git && cd cmd
cargo build --release

# Install to PATH
mkdir -p ~/.local/bin && cp target/release/cmd ~/.local/bin/

Setup

$ cmd setup

? Select your LLM provider:
  ▸ Anthropic (Claude)
    OpenAI
    Ollama (local)
    Azure OpenAI

? Enter your API key: ********

✓ API key stored in system keychain

Use

# Dry-run (default) - shows command, copies to clipboard
$ cmd find all rust files modified today

# Execute with confirmation
$ cmd --enable-execution compress this folder

# Execute without confirmation (careful!)
$ cmd --enable-execution --skip-confirmation list running containers

Examples

# ───────────────────────────────────────────────────
#  Files & directories
# ───────────────────────────────────────────────────
cmd find all rust files modified today
cmd show disk usage sorted by size
cmd count lines of code in this project

# ───────────────────────────────────────────────────
#  Git
# ───────────────────────────────────────────────────
cmd show commits from last week by author
cmd undo last commit but keep changes
cmd what files changed in the last 3 commits

# ───────────────────────────────────────────────────
#  Processes & system
# ───────────────────────────────────────────────────
cmd kill whatever is running on port 3000
cmd show top 10 processes by memory
cmd how much ram is chrome using

# ───────────────────────────────────────────────────
#  Docker
# ───────────────────────────────────────────────────
cmd stop all running containers
cmd remove all dangling images
cmd show logs from the api container

Security First

╔════════════════════════════════════════════════════════════╗
║  SECURITY                                                  ║
╠════════════════════════════════════════════════════════════╣
║                                                            ║
║  [✓] API keys in keychain   Not in .zshrc or plain text    ║
║  [✓] Hidden input           Keys never visible on screen   ║
║  [✓] Memory safety          Secrets zeroed when done       ║
║  [✓] Dry-run default        Commands shown, not executed   ║
║  [✓] Destructive detection  Warns about dangerous cmds     ║
║  [✓] Critical blocking      Blocks rm -rf / and similar    ║
║                                                            ║
╚════════════════════════════════════════════════════════════╝

Next Steps

┌──────────────────────────────────────────────────────┐
│                                                      │
│  [1] Installation ────── Detailed install guide      │
│  [2] Configuration ───── Set up providers & creds    │
│  [3] Usage ───────────── Learn all the features      │
│  [4] Security ────────── Understand safety features  │
│                                                      │
└──────────────────────────────────────────────────────┘

Installation

Requirements

RequirementVersionNotes
Rust1.75+Install via rustup
OSmacOS / LinuxWindows not supported

Quick Install

# Clone and build
git clone https://github.com/Proteusiq/cmd.git
cd cmd
cargo build --release

# Install to local bin
mkdir -p ~/.local/bin
cp target/release/cmd ~/.local/bin/

Add to PATH

If ~/.local/bin isn’t in your PATH, add it:

# For Zsh (~/.zshrc)
export PATH="$HOME/.local/bin:$PATH"

# For Bash (~/.bashrc)
export PATH="$HOME/.local/bin:$PATH"

Then reload your shell:

source ~/.zshrc  # or source ~/.bashrc

Verify Installation

$ cmd --version
cmd 0.5.0

$ cmd --help
Natural language CLI - translate intentions into terminal commands
...

First-Time Setup

After installation, run the setup wizard:

cmd setup

This will:

  1. Let you choose your LLM provider (Claude, OpenAI, Ollama, etc.)
  2. Securely store your API key in the system keychain
  3. Test the connection

Update

To update to the latest version:

cd cmd
git pull
cargo build --release
cp target/release/cmd ~/.local/bin/

Uninstall

# Remove binary
rm ~/.local/bin/cmd

# Remove configuration (optional)
rm -rf ~/.config/cmd

# Remove keychain entries (optional)
cmd config --delete-key anthropic
cmd config --delete-key openai
# Or use Keychain Access on macOS

Troubleshooting

“command not found: cmd”

Make sure ~/.local/bin is in your PATH:

echo $PATH | grep -q '.local/bin' && echo "OK" || echo "Add ~/.local/bin to PATH"

Build errors

Make sure you have the latest Rust:

rustup update

Keychain errors on Linux

Install the Secret Service backend:

# Ubuntu/Debian
sudo apt install libsecret-1-dev gnome-keyring

# Fedora
sudo dnf install libsecret-devel gnome-keyring

# Arch
sudo pacman -S libsecret gnome-keyring

Permission denied

Make sure the binary is executable:

chmod +x ~/.local/bin/cmd

Configuration

Interactive Setup

cmd setup

This will:

  1. Let you choose your LLM provider
  2. Guide you through entering your API key (hidden input)
  3. Store your credentials securely in the system keychain

Credential Storage

API keys are stored securely in your system’s native credential store:

PlatformStorage
macOSKeychain Access
LinuxSecret Service (GNOME Keyring, KWallet)
FallbackEncrypted file (~/.config/cmd/credentials.enc)

Managing Credentials

# View stored API keys (masked)
cmd config --show-keys

# Delete a stored key
cmd config --delete-key anthropic
cmd config --delete-key openai
cmd config --delete-key ollama_host

Priority Order

When loading credentials, cmd checks in this order:

  1. Environment variables (allows temporary overrides)
  2. System keychain (primary storage)
  3. Encrypted file (fallback for headless environments)

This means you can override keychain credentials with environment variables for CI or temporary use.

Execution Settings

Configure how cmd handles command execution:

# View current settings
cmd config --show

# Enable execution mode (still prompts for confirmation)
cmd config --enable-execution

# Skip confirmation prompts (use with caution)
cmd config --skip-confirmation

# Reset to safe defaults
cmd config --disable-execution --require-confirmation

Settings are stored in ~/.config/cmd/settings.toml:

enable_execution = false
skip_confirmation = false

Environment Variables

You can also configure providers via environment variables:

Anthropic (Claude)

export ANTHROPIC_API_KEY=sk-ant-api03-...

Get your API key at console.anthropic.com/settings/keys

Default model: claude-sonnet-4-6

OpenAI

export OPENAI_API_KEY=sk-proj-...

Get your API key at platform.openai.com/api-keys

Default model: gpt-5.2

Ollama (Local)

Ollama runs models locally - no API key needed.

# Install Ollama
brew install ollama

# Pull a model
ollama pull qwen2.5-coder

# Set the host
export OLLAMA_HOST=http://localhost:11434

Default model: qwen2.5-coder

Provider Priority

If multiple providers are configured, cmd uses this priority:

  1. Anthropic
  2. OpenAI
  3. Ollama

Overriding Defaults

Use CLI flags to override the default model or endpoint:

# Use a different model
cmd -m claude-haiku-4-5 "list files"

# Use a custom endpoint
cmd -e https://my-proxy.com/v1/messages "list files"

Azure OpenAI

For Azure-hosted OpenAI, use the setup wizard:

cmd setup
# Select "Azure OpenAI"
# Enter your API key, resource name, and deployment name

Or manually:

export OPENAI_API_KEY=your-azure-api-key

cmd -e "https://your-resource.openai.azure.com/openai/deployments/gpt-5/chat/completions?api-version=2024-02-15-preview" \
    -m gpt-5.2 \
    "list files"

See Providers for more details.

Usage

Basic Usage

Describe what you want to do in plain English:

cmd "your natural language description"

By default, cmd runs in dry-run mode—it shows the generated command and copies it to your clipboard, but does not execute it.

$ cmd find files larger than 100MB
╭──────────────────────────────────────────────────────╮
│ find . -size +100M -type f                           │
╰──────────────────────────────────────────────────────╯
  ↳ copied to clipboard
  ↳ use --enable-execution to run this command

Command Reference

USAGE:
    cmd [OPTIONS] <QUERY>...
    cmd setup
    cmd config [OPTIONS]

ARGUMENTS:
    <QUERY>...    Describe what you want to do in natural language

OPTIONS:
        --enable-execution     Execute the generated command
        --skip-confirmation    Skip the confirmation prompt
    -m, --model <MODEL>        Override the default model
    -e, --endpoint <ENDPOINT>  Override the API endpoint
    -h, --help                 Print help
    -V, --version              Print version

SUBCOMMANDS:
    setup     Configure your LLM provider interactively
    config    Manage settings and API keys

Execution Modes

Dry-Run (Default)

Shows the command without executing:

$ cmd "compress all jpg files"
╭──────────────────────────────────────────────────────╮
│ tar -czvf images.tar.gz *.jpg                        │
╰──────────────────────────────────────────────────────╯
  ↳ copied to clipboard

Execute with Confirmation

$ cmd --enable-execution "compress all jpg files"
╭──────────────────────────────────────────────────────╮
│ tar -czvf images.tar.gz *.jpg                        │
╰──────────────────────────────────────────────────────╯

? Execute this command? (y/N) y

Execute without Confirmation

$ cmd --enable-execution --skip-confirmation "list files"
╭──────────────────────────────────────────────────────╮
│ ls -la                                               │
╰──────────────────────────────────────────────────────╯

total 24
drwxr-xr-x  5 user  staff  160 Mar  3 10:00 .
...

Note: Destructive commands always require confirmation, even with --skip-confirmation.


Configuration Commands

Setup Wizard

cmd setup

Interactive setup to configure your LLM provider and store credentials securely.

View Settings

$ cmd config --show

Current settings:
  enable_execution: false
  skip_confirmation: false

  config: /Users/you/.config/cmd/settings.toml

Change Settings

# Enable execution mode (still prompts for confirmation)
cmd config --enable-execution

# Skip confirmation prompts (use with caution)
cmd config --skip-confirmation

# Reset to safe defaults
cmd config --disable-execution --require-confirmation

Manage API Keys

# View stored keys (masked)
cmd config --show-keys

# Delete a stored key
cmd config --delete-key anthropic
cmd config --delete-key openai
cmd config --delete-key ollama_host

Model and Endpoint Override

Use a Different Model

# Use Claude Haiku instead of default Sonnet
cmd -m claude-haiku-4-5 "list files"

# Use GPT-5.2 mini for faster responses
cmd -m gpt-5.2-mini "show disk usage"

Use a Custom Endpoint

# Use a proxy
cmd -e https://my-proxy.com/v1/messages "list files"

# Use LM Studio locally
cmd -e http://localhost:1234/v1/chat/completions "list files"

# Use a different Ollama host
cmd -e http://192.168.1.100:11434/v1/chat/completions "list files"

Tips and Tricks

Quoting

Simple queries work without quotes:

cmd find large files
cmd show disk usage
cmd list running containers

Use quotes when your query contains shell special characters:

cmd "what's using port 3000?"      # apostrophe and ?
cmd "find *.log files"             # glob (*)
cmd "show $PATH variable"          # dollar sign
cmd "find files with 'test' in name"  # nested quotes
cmd "why isn't this working?"      # apostrophe and ?

Characters that require quoting:

CharactersNameShell behavior
? * [ ]GlobsPattern matching
$DollarVariable expansion
` $()BackticksCommand substitution
&AmpersandBackground process
|PipeCommand piping
;SemicolonCommand separator
< >RedirectsI/O redirection
( )ParensSubshell
{ }BracesBrace expansion
~TildeHome directory
!BangHistory expansion
' " \Quotes/escapeQuoting characters

Tip: When in doubt, use quotes. It never hurts.

Be Specific

More specific queries get better results:

# Less specific
cmd "delete old files"

# More specific
cmd "delete all .log files in /var/log older than 30 days"

Iterate

If the first command isn’t quite right, refine your query:

# First attempt
cmd "find big files"
# → find . -size +1G

# Refined
cmd "find files larger than 100MB, show size in human readable format"
# → find . -size +100M -exec ls -lh {} \;

Preview First

Always use dry-run mode for unfamiliar commands:

# See what it generates
cmd "recursively change permissions"

# Review the command, then execute if correct
cmd --enable-execution "recursively chmod 755 all directories"

Security

╔═══════════════════════════════════════════════════════════════════════════╗
║                                                                           ║
║   ███████╗███████╗ ██████╗██╗   ██╗██████╗ ██╗████████╗██╗   ██╗          ║
║   ██╔════╝██╔════╝██╔════╝██║   ██║██╔══██╗██║╚══██╔══╝╚██╗ ██╔╝          ║
║   ███████╗█████╗  ██║     ██║   ██║██████╔╝██║   ██║    ╚████╔╝           ║
║   ╚════██║██╔══╝  ██║     ██║   ██║██╔══██╗██║   ██║     ╚██╔╝            ║
║   ███████║███████╗╚██████╗╚██████╔╝██║  ██║██║   ██║      ██║             ║
║   ╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝  ╚═╝╚═╝   ╚═╝      ╚═╝             ║
║                                                                           ║
║   Security is not an afterthought—it's built into every layer.            ║
║                                                                           ║
╚═══════════════════════════════════════════════════════════════════════════╝

Safe by Default

┌─────────────────────────────────────────────────────────────────┐
│  DEFAULT MODE: DRY-RUN                                          │
│                                                                 │
│  [✓] Shows the generated command                                │
│  [✓] Copies to clipboard                                        │
│  [✗] Does NOT execute                                           │
└─────────────────────────────────────────────────────────────────┘
$ cmd "list all files"
╭──────────────────────────────────────────────────────╮
│ ls -la                                               │
╰──────────────────────────────────────────────────────╯
  ↳ copied to clipboard
  ↳ use --enable-execution to run this command

To execute commands, you must explicitly opt-in with --enable-execution.


Credential Security

System Keychain Storage

┌──────────────────────────────────────────────────────────────────┐
│  CREDENTIAL STORAGE                                              │
├──────────────┬───────────────────────────────────────────────────┤
│  macOS       │  Keychain Access                                  │
│  Linux       │  Secret Service (GNOME Keyring, KWallet)          │
│  Windows     │  Credential Manager                               │
│  Fallback    │  AES-256-GCM encrypted file                       │
└──────────────┴───────────────────────────────────────────────────┘

Why this matters:

  ┌─ OLD WAY (insecure) ────────────────────────────────┐
  │                                                     │
  │   $ echo 'export ANTHROPIC_API_KEY=sk-...' >> ~/.zshrc
  │                                                     │
  │   [✗] Plain text on disk                            │
  │   [✗] Readable by any process                       │
  │   [✗] Ends up in shell history                      │
  │   [✗] Accidentally committed to git                 │
  │                                                     │
  └─────────────────────────────────────────────────────┘

  ┌─ cmd WAY (secure) ──────────────────────────────────┐
  │                                                     │
  │   $ cmd setup                                       │
  │   ? API key: ········                               │
  │   ✓ Saved to system keychain                        │
  │                                                     │
  │   [✓] Encrypted at rest by OS                       │
  │   [✓] Protected by system login                     │
  │   [✓] Never in plain text files                     │
  │   [✓] Never in shell history                        │
  │                                                     │
  └─────────────────────────────────────────────────────┘

Encrypted File Fallback

For headless servers without keychain access:

┌─────────────────────────────────────────────────────────────────┐
│  ENCRYPTION SPEC                                                │
├─────────────────────────────────────────────────────────────────┤
│  Algorithm      │  AES-256-GCM (authenticated encryption)       │
│  Key Derivation │  Argon2id (memory-hard, GPU-resistant)        │
│  Location       │  ~/.config/cmd/credentials.enc                │
│  Permissions    │  600 (owner read/write only)                  │
└─────────────────────────────────────────────────────────────────┘

Hidden Input

API keys are never visible when typing:

$ cmd setup
? Select your LLM provider: Claude (Anthropic)
Get your API key at: https://console.anthropic.com/settings/keys

? API key: ········································
           ▲
           └── Characters hidden, not echoed

✓ API key saved to system keychain

Memory Safety

┌─────────────────────────────────────────────────────────────────┐
│  MEMORY PROTECTION                                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ┌──────────┐     ┌──────────┐     ┌──────────┐                │
│   │  Input   │ ──▶ │   Use    │ ──▶ │  Zero    │                │
│   │  Secret  │     │  Secret  │     │  Memory  │                │
│   └──────────┘     └──────────┘     └──────────┘                │
│                                           │                     │
│                                           ▼                     │
│                                    ┌──────────┐                 │
│                                    │  0x0000  │                 │
│                                    │  0x0000  │                 │
│                                    │  0x0000  │                 │
│                                    └──────────┘                 │
│                                                                 │
│   • SecretKey wrapper zeros memory on drop                      │
│   • Compiler fences prevent optimization skip                   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Input Validation

# Blocked suspicious endpoints
$ cmd setup
? API endpoint URL: https://evil.ngrok.io/steal

╔════════════════════════════════════════════════════════════════╗
║  [ERROR] Suspicious endpoint detected                          ║
║                                                                ║
║  Domain 'ngrok.io' is commonly used for data exfiltration.     ║
║  This could be an attempt to steal your API key.               ║
╚════════════════════════════════════════════════════════════════╝

Execution Safety

Execution Modes

┌────────────────────┬──────────────────────────────────────────────────┐
│  MODE              │  COMMAND                                         │
├────────────────────┼──────────────────────────────────────────────────┤
│  Dry-run           │  cmd "query"                                     │
│  (default)         │  → Show only, copy to clipboard                  │
├────────────────────┼──────────────────────────────────────────────────┤
│  With confirmation │  cmd --enable-execution "query"                  │
│                    │  → Prompt before executing                       │
├────────────────────┼──────────────────────────────────────────────────┤
│  Auto-execute      │  cmd --enable-execution --skip-confirmation ...  │
│  (dangerous)       │  → Execute immediately                           │
└────────────────────┴──────────────────────────────────────────────────┘

Destructive Command Detection

┌─────────────────────────────────────────────────────────────────────────┐
│  THREAT LEVELS                                                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   ┌─────────┐                                                           │
│   │ WARNING │  rm, mv, chmod, chown, sudo, git push --force             │
│   │   ⚠️    │  → Prompts for confirmation                               │
│   └─────────┘                                                           │
│                                                                         │
│   ┌─────────┐                                                           │
│   │ DANGER  │  rm -rf, dd, mkfs, curl|sh, kill -9                       │
│   │   🔥    │  → Always prompts, even with --skip-confirmation          │
│   └─────────┘                                                           │
│                                                                         │
│   ┌─────────┐                                                           │
│   │CRITICAL │  rm -rf /, rm -rf ~, fork bombs, dd /dev/sda              │
│   │   🛑    │  → BLOCKED ENTIRELY                                       │
│   └─────────┘                                                           │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Critical Commands = Blocked

$ cmd --enable-execution "delete everything"
╭──────────────────────────────────────────────────────╮
│ rm -rf /                                             │
╰──────────────────────────────────────────────────────╯

╔══════════════════════════════════════════════════════════════════╗
║  🛑 CRITICAL - BLOCKED                                           ║
╠══════════════════════════════════════════════════════════════════╣
║                                                                  ║
║  • CRITICAL: Removes entire filesystem                           ║
║  • DANGER: Recursive forced deletion                             ║
║                                                                  ║
║  This command is too dangerous to execute.                       ║
║  If you really need to run this, copy and execute it manually.   ║
║                                                                  ║
╚══════════════════════════════════════════════════════════════════╝

Forced Confirmation

Destructive commands always prompt, even with --skip-confirmation:

$ cmd --enable-execution --skip-confirmation "delete node_modules"
╭──────────────────────────────────────────────────────╮
│ rm -rf node_modules                                  │
╰──────────────────────────────────────────────────────╯

⚠️  DANGEROUS
  • DANGER: Recursive forced deletion

? This is a destructive command. Execute anyway? (y/N) _

Managing Credentials

# View stored keys (masked)
$ cmd config --show-keys
┌─────────────────────────────────────────────────────┐
│  Stored API keys:                                   │
│                                                     │
│    Anthropic: sk-ant-*************************      │
│    OpenAI:    (not set)                             │
│    Ollama:    (not set)                             │
└─────────────────────────────────────────────────────┘

# Delete a key
$ cmd config --delete-key anthropic
✓ Deleted anthropic API key

Best Practices

╔═══════════════════════════════════════════════════════════════════════════╗
║  SECURITY CHECKLIST                                                       ║
╠═══════════════════════════════════════════════════════════════════════════╣
║                                                                           ║
║  [1] Always review commands before executing                              ║
║                                                                           ║
║  [2] Start with dry-run mode until comfortable                            ║
║                                                                           ║
║  [3] Use confirmation prompts — don't skip unless automating              ║
║                                                                           ║
║  [4] Be careful with wildcards — rm *.log safer than rm -rf *             ║
║                                                                           ║
║  [5] Test destructive commands with echo first:                           ║
║      $ echo rm -rf folder/                                                ║
║                                                                           ║
║  [6] Use version control — commit before destructive commands             ║
║                                                                           ║
║  [7] Use env vars for CI — don't store keys in build configs              ║
║                                                                           ║
╚═══════════════════════════════════════════════════════════════════════════╝

Reporting Security Issues

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│  Found a vulnerability?                                         │
│                                                                 │
│  [1] Open a private security advisory on GitHub                 │
│  [2] Email the maintainers directly                             │
│                                                                 │
│  ⚠️  Please do NOT open public issues for security bugs         │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Examples

File Operations

# Find large files
cmd "find files larger than 100MB"

# Find recently modified files
cmd "find files modified in the last hour"

# Count files by extension
cmd "count files by extension in current directory"

# Delete old files (use --dry first!)
cmd --dry "delete all .log files older than 30 days"

Git Operations

# Show recent commits
cmd "show commits from last week with author names"

# Find commits by message
cmd "find commits mentioning 'bug fix'"

# Show changed files
cmd "list files changed in the last commit"

# Undo last commit
cmd --dry "undo the last commit but keep changes"

Docker Operations

# Container management
cmd "list all running containers"
cmd "stop all running containers"
cmd "remove all stopped containers"

# Image management
cmd "list all docker images sorted by size"
cmd "remove dangling docker images"

# Logs
cmd "show logs from container named 'web' last 100 lines"

System Monitoring

# Process information
cmd "show top 10 processes using most CPU"
cmd "show top 10 processes using most memory"

# Disk usage
cmd "show disk usage sorted by size"
cmd "find largest directories in home folder"

# Network
cmd "show listening ports"
cmd "show active network connections"

Text Processing

# Search in files
cmd "find all TODO comments in rust files"
cmd "count lines of code in python files"

# File manipulation
cmd "replace tabs with spaces in all .py files"
cmd "convert all filenames to lowercase"

Compression

# Create archives
cmd "compress this folder into a tar.gz"
cmd "create a zip file of all .txt files"

# Extract
cmd "extract this tar.gz file"

Safety Tips

  1. Always use --dry first for destructive operations
  2. Review the command before executing
  3. Start specific - the more details you provide, the better the command

Architecture

Vibe CLI follows the Functional Core, Imperative Shell pattern for maintainability and testability.

Project Structure

src/
  main.rs           # CLI entry point (thin shell)
  lib.rs            # Module exports
  core/
    mod.rs
    config.rs       # Provider detection (pure, testable)
  providers/
    mod.rs
    anthropic.rs    # Anthropic API client
    openai.rs       # OpenAI/Ollama API client
  cli/
    mod.rs
    output.rs       # Spinner, colors, clipboard

Design Principles

Functional Core

The core/ module contains pure functions with no side effects:

  • Config detection - Takes environment variable getter as a parameter
  • Testable - Unit tests don’t need mocks for environment variables
  • Predictable - Same inputs always produce same outputs
#![allow(unused)]
fn main() {
// Pure function - testable without mocking env vars
pub fn detect(
    model_override: Option<&str>,
    endpoint_override: Option<&str>,
    env_vars: &dyn Fn(&str) -> Option<String>,
) -> Option<Config>
}

Imperative Shell

The main.rs is a thin shell that:

  1. Parses CLI arguments
  2. Wires dependencies together
  3. Handles I/O (network, terminal, clipboard)
  4. Reports errors

Side Effects Isolated

The providers/ and cli/ modules handle I/O:

  • providers/ - HTTP calls to LLM APIs
  • cli/ - Terminal output, clipboard operations

Data Flow

┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│   CLI Args  │ ──▶ │  Config      │ ──▶ │  Provider   │
│   (clap)    │     │  Detection   │     │  API Call   │
└─────────────┘     └──────────────┘     └─────────────┘
                                               │
                                               ▼
┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│   Execute   │ ◀── │  Display     │ ◀── │  LLM        │
│   Command   │     │  Result      │     │  Response   │
└─────────────┘     └──────────────┘     └─────────────┘

Error Handling

  • Uses anyhow for error propagation with context
  • Semantic exit codes via exitcode crate
  • Friendly panic messages via human-panic

Dependencies

CratePurpose
clapCLI argument parsing
anyhowError handling
ureqSync HTTP client
serdeJSON serialization
owo-colorsTerminal colors
spinoffLoading spinner
human-panicFriendly crash reports
exitcodeSemantic exit codes

Providers

cmd supports multiple LLM providers through a unified interface.

Supported Providers

ProviderAPI FormatAuthLocal
AnthropicMessages APIAPI KeyNo
OpenAIChat CompletionsAPI KeyNo
OllamaOpenAI-compatibleNoneYes

Anthropic

Uses Claude models via the Messages API.

Endpoint: https://api.anthropic.com/v1/messages

Authentication: x-api-key header

Default model: claude-sonnet-4-6

Available models:

  • claude-sonnet-4-6 (default, balanced)
  • claude-opus-4-6 (most capable)
  • claude-haiku-4-5 (fast, cheap)

OpenAI

Uses GPT models via the Chat Completions API.

Endpoint: https://api.openai.com/v1/chat/completions

Authentication: Authorization: Bearer header

Default model: gpt-5.2

Available models:

  • gpt-5.2 (default, latest)
  • gpt-5.2-mini (fast, cheap)
  • gpt-5.1 (previous generation)

Ollama

Runs models locally using Ollama’s OpenAI-compatible API.

Endpoint: http://localhost:11434/v1/chat/completions

Authentication: None required

Default model: qwen2.5-coder

Setup:

# Install Ollama
brew install ollama

# Pull a coding model
ollama pull qwen2.5-coder
ollama pull codellama
ollama pull deepseek-coder

# Start server (if not running)
ollama serve

Azure OpenAI

Azure OpenAI uses the OpenAI-compatible format with a custom endpoint.

Endpoint format: https://<resource-name>.openai.azure.com/openai/deployments/<deployment-name>/chat/completions?api-version=<version>

# Set your Azure API key
export OPENAI_API_KEY=your-azure-api-key

# Use with custom endpoint
cmd -e "https://myresource.openai.azure.com/openai/deployments/gpt-5/chat/completions?api-version=2024-02-15-preview" \
    -m gpt-5.2 \
    "list files"

Custom Endpoints

Use the -e flag to specify a custom endpoint:

# Use a proxy
cmd -e https://my-anthropic-proxy.com/v1/messages "list files"

# Use a different Ollama host
cmd -e http://192.168.1.100:11434/v1/chat/completions "list files"

# Use a self-hosted vLLM server
cmd -e http://localhost:8000/v1/chat/completions -m my-model "list files"

# Use LM Studio
cmd -e http://localhost:1234/v1/chat/completions "list files"

Adding New Providers

Most providers are OpenAI-compatible. To use them:

  1. Set the appropriate API key (uses OPENAI_API_KEY)
  2. Use -e to specify their endpoint
  3. Use -m to specify the model name
# Groq (OpenAI-compatible, fast inference)
export OPENAI_API_KEY=gsk_...
cmd -e https://api.groq.com/openai/v1/chat/completions -m llama-3.3-70b-versatile "list files"

# Together AI
export OPENAI_API_KEY=...
cmd -e https://api.together.xyz/v1/chat/completions -m mistralai/Mixtral-8x7B-Instruct-v0.1 "list files"

# Fireworks AI
export OPENAI_API_KEY=...
cmd -e https://api.fireworks.ai/inference/v1/chat/completions -m accounts/fireworks/models/llama-v3-70b-instruct "list files"

# OpenRouter (access multiple providers)
export OPENAI_API_KEY=sk-or-...
cmd -e https://openrouter.ai/api/v1/chat/completions -m anthropic/claude-sonnet-4-6 "list files"

# Deepseek
export OPENAI_API_KEY=...
cmd -e https://api.deepseek.com/v1/chat/completions -m deepseek-coder "list files"

Provider Comparison

ProviderLatencyCostLocalBest For
AnthropicMedium$$NoAccuracy
OpenAIMedium$$NoGeneral use
Azure OpenAIMedium$$NoEnterprise
GroqFast$NoSpeed
OllamaVariesFreeYesPrivacy
TogetherFast$NoOpen models

Contributing

Contributions are welcome! Here’s how to get started.

Development Setup

# Clone the repository
git clone https://github.com/Proteusiq/cmd.git
cd cmd

# Build
cargo build

# Run tests
cargo test

# Run with development build
cargo run -- "list files"

Code Style

We follow the conventions in AGENTS.md:

  • Simplicity is king - the simplest solution that works is the best
  • Functional over OOP - pure functions, composition, immutability
  • No inline comments - code should be self-documenting

Before Committing

cargo fmt
cargo clippy -- -D warnings
cargo test

Project Structure

src/
  main.rs           # CLI entry point (keep thin)
  lib.rs            # Module exports
  core/             # Pure business logic (testable)
  providers/        # LLM API clients (side effects)
  cli/              # Terminal I/O (side effects)

Adding a New Provider

  1. Create src/providers/newprovider.rs
  2. Implement the request/response types
  3. Add to src/providers/mod.rs
  4. Update config detection in src/core/config.rs

Testing

# Run all tests
cargo test

# Run specific test
cargo test detects_anthropic

# Run with output
cargo test -- --nocapture

Documentation

Documentation uses mdBook.

# Install mdBook
cargo install mdbook

# Serve locally
cd docs
mdbook serve

# Build
mdbook build

Commit Messages

Follow the format:

type: short description
TypeUse
feat:New feature
fix:Bug fix
docs:Documentation
refactor:Code restructure
test:Tests
chore:Maintenance

Pull Requests

  1. Fork the repository
  2. Create a feature branch (feat/my-feature)
  3. Make your changes
  4. Run tests and linting
  5. Submit a PR with a clear description

License

By contributing, you agree that your contributions will be licensed under the Apache 2.0 License.