By Sagar Shankaran, Founder of CallSphere
Build an AI agent that translates natural language into shell commands, explains what each command does, asks for confirmation before executing dangerous operations, and learns from command history.
Key takeaways
The command line is powerful but has a steep learning curve. Developers frequently search the internet for the right flags to pass to git, docker, kubectl, or ffmpeg. A CLI assistant agent lets you describe what you want in plain English, translates it into the correct command, explains what it will do, and optionally executes it after confirmation.
Unlike static cheatsheets, the agent understands your current context — your OS, installed tools, and working directory — to produce commands that actually work.
The agent maps natural language to shell commands, classifying each as safe or dangerous before execution.
Hear it before you finish reading
Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.
flowchart LR
INPUT(["User intent"])
PARSE["Parse plus<br/>classify"]
PLAN["Plan and tool<br/>selection"]
AGENT["Agent loop<br/>LLM plus tools"]
GUARD{"Guardrails<br/>and policy"}
EXEC["Execute and<br/>verify result"]
OBS[("Trace and metrics")]
OUT(["Outcome plus<br/>next action"])
INPUT --> PARSE --> PLAN --> AGENT --> GUARD
GUARD -->|Pass| EXEC --> OUT
GUARD -->|Fail| AGENT
AGENT --> OBS
style AGENT fill:#4f46e5,stroke:#4338ca,color:#fff
style GUARD fill:#f59e0b,stroke:#d97706,color:#1f2937
style OBS fill:#ede9fe,stroke:#7c3aed,color:#1e1b4b
style OUT fill:#059669,stroke:#047857,color:#fff
import os
import subprocess
import shutil
from dataclasses import dataclass
from openai import OpenAI
client = OpenAI()
@dataclass
class CommandResult:
command: str
explanation: str
is_dangerous: bool
output: str | None = None
error: str | None = None
executed: bool = False
class CLIAssistantAgent:
def __init__(self, model: str = "gpt-4o"):
self.model = model
self.history: list[dict] = []
self.dangerous_patterns = [
"rm -rf", "mkfs", "dd if=", "> /dev/",
"chmod 777", ":(){ :|:& };:",
"DROP TABLE", "DELETE FROM",
"--force", "--hard",
]
def get_system_context(self) -> str:
import platform
shell = os.environ.get("SHELL", "unknown")
cwd = os.getcwd()
tools = {}
for tool in ["git", "docker", "kubectl", "python", "node"]:
tools[tool] = shutil.which(tool) is not None
return (
f"OS: {platform.system()} {platform.release()}\n"
f"Shell: {shell}\n"
f"CWD: {cwd}\n"
f"Available tools: {tools}"
)
The core translation step uses the system context to produce environment-specific commands.
import json
def translate(self, user_request: str) -> CommandResult:
context = self.get_system_context()
history_context = ""
if self.history:
recent = self.history[-5:]
history_context = "Recent commands:\n" + "\n".join(
f"- {h['request']} -> {h['command']}" for h in recent
)
response = client.chat.completions.create(
model=self.model,
messages=[
{"role": "system", "content": f"""You are a CLI assistant.
Translate user requests into shell commands.
System info:
{context}
{history_context}
Return JSON with:
- "command": the shell command to execute
- "explanation": plain English explanation of what it does
- "is_dangerous": boolean, true if the command modifies or deletes data
IMPORTANT: Use tools available on this system. Adapt commands
for the detected OS (e.g., use gsed on macOS if needed).
Return ONLY valid JSON."""},
{"role": "user", "content": user_request},
],
temperature=0,
response_format={"type": "json_object"},
)
data = json.loads(response.choices[0].message.content)
result = CommandResult(
command=data["command"],
explanation=data["explanation"],
is_dangerous=data.get("is_dangerous", False),
)
for pattern in self.dangerous_patterns:
if pattern in result.command:
result.is_dangerous = True
break
return result
Notice the double check: the LLM classifies danger, and then the agent applies its own pattern-based check. This defense-in-depth approach prevents the LLM from accidentally marking a destructive command as safe.
Dangerous commands require explicit user confirmation before running.
def execute(self, result: CommandResult, force: bool = False) -> CommandResult:
if result.is_dangerous and not force:
result.error = "BLOCKED: Dangerous command requires confirmation"
return result
try:
proc = subprocess.run(
result.command,
shell=True,
capture_output=True,
text=True,
timeout=30,
cwd=os.getcwd(),
)
result.output = proc.stdout
result.error = proc.stderr if proc.returncode != 0 else None
result.executed = True
except subprocess.TimeoutExpired:
result.error = "Command timed out after 30 seconds"
except Exception as e:
result.error = str(e)
self.history.append({
"request": "executed",
"command": result.command,
"success": result.error is None,
})
return result
The agent runs as a REPL that continuously accepts requests.
Still reading? Stop comparing — try CallSphere live.
CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.
def run_interactive(self):
print("CLI Assistant (type 'exit' to quit)")
print("-" * 40)
while True:
user_input = input("\n> ").strip()
if user_input.lower() in ("exit", "quit"):
break
if not user_input:
continue
result = self.translate(user_input)
print(f"\nCommand: {result.command}")
print(f"Explanation: {result.explanation}")
if result.is_dangerous:
print("\n[WARNING] This command modifies or deletes data.")
confirm = input("Execute? (y/N): ").strip().lower()
if confirm != "y":
print("Cancelled.")
continue
result = self.execute(result, force=True)
else:
result = self.execute(result)
if result.output:
print(f"\nOutput:\n{result.output}")
if result.error:
print(f"\nError:\n{result.error}")
agent = CLIAssistantAgent()
agent.run_interactive()
The agent should never interpolate user input directly into shell commands. The LLM generates the full command as a string, and the dangerous-pattern checker blocks known attack vectors like ; rm -rf / or backtick injection. For additional safety, run commands in a restricted subprocess with limited permissions and environment variables.
Yes. The LLM naturally understands piping, redirection, and command chaining. A request like "find all Python files larger than 1MB and sort by size" produces find . -name '*.py' -size +1M -exec ls -lh {} + | sort -k5 -h. The explanation breaks down each step so the user understands what each part does.
The last five commands are included in the prompt context. This allows the agent to understand follow-up requests like "now do the same but only for .js files" or "run that again with verbose output." The agent resolves these references against recent history.
#CLITools #AIAgents #Python #Shell #DeveloperProductivity #AgenticAI #LearnAI #AIEngineering

Written by
Sagar Shankaran· Founder, CallSphere
LinkedInSagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
A founder's guide to the personal AI assistant market: best AI assistant apps, business-grade options, and how CallSphere's voice agent fits in.
A founder's guide to free AI agents, low-code AI agent builders, and how to know when you should pay for a real platform like CallSphere.
Graphiti is the open-source temporal knowledge graph for AI agents in 2026. Learn how bi-temporal memory beats vector RAG for voice agents and long-running LLMs.
Chatbot app vs ChatGPT in 2026: a founder's clear take on the difference, when to use which, and how a real AI chatbot app development works.
How we built a fault-tolerant HVAC emergency triage and tech-dispatch platform on Kubernetes — three-tier CQRS, 11 micro-agents on the OpenAI Agents SDK + LangGraph, NATS JetStream, DTMF/SMS/WebSocket acceptance, circuit breakers, and an evaluation pipeline that catches regressions before they wake a tech at 3 AM.
Head-to-head: OpenAI Frontier and Anthropic's managed agent stack — strengths, fit, and what each means for enterprise AI voice and chat deployment.
© 2026 CallSphere Inc. All rights reserved.
Made within San Francisco