Back to Articles

LLM-CLI: A Crystal-Fast Command Generator That Learns What You Mean

[ View on GitHub ]

LLM-CLI: A Crystal-Fast Command Generator That Learns What You Mean

Hook

The average developer googles command syntax 15-20 times per day. What if your shell could just understand what you meant instead?

Context

We've all been there: you know exactly what you want to accomplish—compress this directory, find files modified in the last week, set up a reverse SSH tunnel—but the exact incantation of flags and arguments escapes you. So you context-switch to a browser, wade through StackOverflow answers from 2014, copy a command, modify it, and hope it works.

The traditional solution has been shell completion, man pages, and tools like tldr. But these require you to already know the command name. LLM-CLI takes a different approach: treat natural language as the interface. Describe what you want in plain English, get a shell command back, review it, and execute. It's the same pattern that's made ChatGPT valuable for coding, but optimized for the tight feedback loop of command-line work. Built in Crystal rather than Python or JavaScript, it prioritizes startup speed—because waiting 2 seconds for a Python runtime to initialize defeats the purpose of a CLI productivity tool.

Technical Insight

The architecture is refreshingly straightforward: LLM-CLI is a thin client that wraps OpenAI's chat completion API with prompts engineered specifically for shell command generation. Written in Crystal, it compiles to a native binary with minimal dependencies and near-instant startup times.

The tool operates in two distinct modes controlled by command-line flags. Default mode generates executable shell commands, while query mode (-q) returns explanatory text for informational questions. Here's what a typical interaction looks like:

# Command generation mode (default)
$ llm find large files in home directory
# Returns: find ~ -type f -exec ls -lh {} \; | sort -k5 -hr | head -20

# Query mode for explanations
$ llm -q "what does rsync -avz do"
# Returns: Explanation of rsync flags without generating a command

The critical design decision is the interactive parameter prompting system. When you make a vague request, LLM-CLI doesn't just fail or make assumptions—it asks follow-up questions. Request "compress this directory" and it might prompt for the target directory, desired compression format, or whether to preserve the original. This creates a conversational refinement loop that's far more efficient than re-running commands with additional context.

Under the hood, the system prompt engineering does the heavy lifting. The tool constructs prompts that instruct GPT to return only executable commands without explanatory text in command mode, and to explicitly ask for missing parameters rather than hallucinating defaults. The Crystal implementation reads OpenAI API credentials from environment variables (OPENAI_API_KEY) and makes HTTP requests to the chat completion endpoints.

Here's a simplified view of how the prompt structure works:

# System prompt for command generation mode
system_prompt = <<-PROMPT
  You are a shell command generator. Return ONLY the command, no explanations.
  If information is missing, ask the user a specific question.
  Target shell: #{detect_shell}
  OS: #{detect_os}
  PROMPT

# User's natural language request gets appended
user_message = "find files larger than 1GB modified today"

# Response parsing extracts the command
command = parse_response(api_call(system_prompt, user_message))

The OS and shell detection is particularly important—the same intent ("show network connections") requires netstat on Linux but lsof might be preferred on macOS. Crystal's system introspection makes this detection lightweight and fast.

One subtle but crucial detail: LLM-CLI presents generated commands for user confirmation before execution. This isn't just a safety feature; it's a learning opportunity. You see the command structure, understand the flags used, and gradually internalize patterns. Over time, you might find yourself typing find ~ -name "*.log" -mtime -7 directly because you've seen LLM-CLI generate it enough times.

Gotcha

The biggest limitation is provider lock-in. Despite the generic name "llm-cli," the tool only supports OpenAI's API. You can't point it at a local Ollama instance, use Anthropic's Claude, or leverage cheaper alternatives like Together AI or Groq. For developers working in air-gapped environments or organizations with OpenAI restrictions, this is a non-starter.

The Crystal toolchain requirement creates a distribution challenge. Unlike Go (with its static binaries) or Python (with ubiquitous runtimes), Crystal isn't commonly installed on developer machines. You can't just brew install llm-cli and start working—you need to build from source with a Crystal compiler, or distribute pre-compiled binaries for each platform yourself. This makes team adoption harder; getting five developers to build a Crystal project is a tougher sell than pip install shell-gpt.

Safety mechanisms are minimal. While the tool does prompt for confirmation before executing commands, there's no sandboxing, dry-run mode with explanation of what will happen, or special handling for obviously destructive operations like rm -rf. A misinterpreted prompt could generate sudo rm -rf /var when you meant something else, and only your quick reading stands between you and disaster. More mature tools in this space include rollback mechanisms or explicit confirmations for commands containing certain dangerous patterns.

Verdict

Use if: You're already in the Crystal ecosystem and want a fast, purpose-built command generator; you frequently forget command syntax but know conceptually what you want; you have an OpenAI API key and don't mind the vendor lock-in; or you value sub-100ms startup times and are willing to build from source for that performance. The interactive parameter refinement alone makes this worthwhile for exploratory command construction. Skip if: You need multi-provider LLM support (especially local models); you're working in teams that need easy installation without compiling; you want advanced safety features like command simulation or automatic backup creation before destructive operations; or you're looking for a more comprehensive AI coding assistant rather than a single-purpose command generator. For those cases, shell_gpt or GitHub Copilot CLI offer broader ecosystems and easier onboarding, even if they sacrifice some startup speed.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/llm-engineering/stakach-llm-cli.svg)](https://starlog.is/api/badge-click/llm-engineering/stakach-llm-cli)