← Articles

// FIELD NOTE

Give Your Terminal AI Super Powers

Cory LaNou

Cory LaNou

Give Your Terminal AI Super Powers

Give Your Terminal AI Super Powers

Overview

I'm a longtime Vim and TMUX user who briefly switched to Cursor for its AI features. The one thing I missed when returning to the terminal? Command K - the ability to ask "what command does X?" and get an instant answer. Here's how I replicated that with two simple scripts.

Why I Left (and Returned to) the Terminal

I've been using Vim and TMUX for years. When AI coding tools became dominant, I reluctantly switched to Cursor. As much as I hated leaving my well-configured Vim setup, the agentic-style programming was too compelling to ignore.

But there were problems:

  • The IDE was cumbersome and used more memory than Vim
  • Every Cursor instance runs its own gopls, eating 500MB+ each
  • With 50 sessions open, that's potentially 25GB of RAM just for language servers
  • My machine was slowing down significantly

So I moved back to TMUX and terminal-based workflows. But I missed one killer feature from Cursor.

The Feature I Missed

In Cursor, you can press Command K in the terminal and type things like:

"What is running on port 8888?"

It figures out the command (lsof -i :8888), shows it to you, and you hit enter to run it. Simple, but incredibly useful.

I got tired of looking up commands I don't use daily. FFmpeg flags, obscure git operations, network diagnostics - there's always something I need to look up.

The Solution: Two Shell Functions

I created two functions: how and pls. They serve different purposes:

  • how - Tell me the command (fast, doesn't execute anything)
  • pls - Please do this task (agentic, uses tools to accomplish it)

The how Command

how do I see what is running on port 8888

This sends your question to Claude, which returns the command and puts it directly in your prompt ready to execute. You can review it, modify it, or just hit enter. It also copies the command to your clipboard.

how do I see the largest file in this directory
how do I squash the last 3 commits
how do I find which commit introduced a bug

The pls Command

Sometimes you don't want a command - you want the AI to actually do the work:

pls find the top five largest files in my home folder
pls what Go version is this project using
pls show me any TODO comments in this directory

This runs Claude in agentic mode with limited, safe tools. It can read files, search, and explore - but can't modify anything.

The Code: Claude Version

Here's the actual code I use daily. These go in your .zshrc or Oh My Zsh custom directory.

The _how Function

# how - Tell me the command (fast, no tools)
_how() {
  if [[ -z "$*" ]]; then
    echo "Usage: how <what command do you need?>"
    return 1
  fi

  local result
  result=$(command claude -p --model sonnet --max-turns 1 --append-system-prompt \
    "You are a command-line expert. The user will ask about a shell command. \
Respond with ONLY the command itself - no explanation, no markdown, no code \
blocks, no backticks, just the raw command. If multiple commands are needed, \
separate with && or ;. Never include any other text. Example: user asks \
'how to list files' you respond with just: ls -la" \
    "$*" 2>/dev/null)

  # Strip any markdown formatting that might slip through
  result=$(echo "$result" | sed 's/^```[a-z]*$//' | sed 's/^```$//' | sed '/^$/d' | tr -d '`')

  if [[ -n "$result" ]]; then
    echo "$result" | pbcopy
    echo "Command ready (also copied to clipboard):"
    print -z "$result"
  else
    echo "No result from Claude"
    return 1
  fi
}
Key details:
  • command claude - Uses command to bypass any shell aliases and call the real binary
  • -p - Prompt mode, single question/answer, no interactive session
  • --model sonnet - Uses the faster Sonnet model for quick responses
  • --max-turns 1 - Prevents multi-turn conversations
  • --append-system-prompt - Adds instructions without replacing the default system prompt
  • sed pipeline - Strips any markdown code blocks or backticks that slip through
  • pbcopy - Copies to macOS clipboard (use xclip on Linux)
  • print -z - Puts the command into the zsh line editor buffer, ready to execute

The _pls Function

# pls - Please do this task (agentic, uses tools)
_pls() {
  if [[ -z "$*" ]]; then
    echo "Usage: pls <what do you want me to do?>"
    return 1
  fi

  command claude -p --model haiku \
    --allowedTools "Read" "Glob" "Grep" "Bash(ls:*)" "Bash(find:*)" \
    "Bash(cat:*)" "Bash(head:*)" "Bash(tail:*)" "Bash(wc:*)" \
    "Bash(file:*)" "Bash(which:*)" "Bash(type:*)" "Bash(man:*)" \
    --append-system-prompt \
    "You are a helpful assistant. The user wants you to actually perform \
a task - search for files, look up information, explore the filesystem, \
etc. Use your tools to accomplish the task. Be concise in your response." \
    "$*"
}
Key details:
  • --model haiku - Uses the faster, cheaper Haiku model for simple tasks
  • --allowedTools - Restricts which tools Claude can use (read-only operations)
  • No Bash(rm:*) or write operations - it can explore but not modify

The Aliases (Critical!)

# Claude helpers (use noglob to prevent globbing issues)
alias how='noglob _how'
alias pls='noglob _pls'

Why noglob? This is the magic that makes natural language work in the shell.

Without noglob, when you type:

how do I find files with *.go extension?

Zsh tries to expand *.go before passing it to the function. It might become:

how do I find files with main.go utils.go server.go extension?

Or worse, if no .go files exist in the current directory, zsh throws an error.

The noglob prefix tells zsh: "Don't expand anything - pass the entire string as-is." This lets you use question marks, asterisks, and other special characters in your natural language queries.

The Code: Codex Version

If you're using OpenAI's Codex CLI instead of Claude:

The _how_codex Function

# how_codex - Tell me the command (Codex version)
_how_codex() {
  if [[ -z "$*" ]]; then
    echo "Usage: how <what command do you need?>"
    return 1
  fi

  local result
  result=$(command codex exec \
    "You are a command-line expert. Respond with ONLY the command - no \
explanation, no markdown, no backticks. Question: $*" 2>/dev/null | tail -1)

  result=$(echo "$result" | tr -d '`')

  if [[ -n "$result" ]]; then
    echo "$result" | pbcopy
    echo "Command ready (also copied to clipboard):"
    print -z "$result"
  else
    echo "No result from Codex"
    return 1
  fi
}

The _pls_codex Function

# pls_codex - Do this task (Codex version)
_pls_codex() {
  if [[ -z "$*" ]]; then
    echo "Usage: pls <what do you want me to do?>"
    return 1
  fi

  command codex exec \
    "You are a helpful assistant. Perform this task and be concise: $*" 2>/dev/null
}

The Aliases

alias how_codex='noglob _how_codex'
alias pls_codex='noglob _pls_codex'
Codex differences:
  • Uses codex exec for non-interactive mode
  • Output includes headers, so we use tail -1 to get just the response
  • 2>/dev/null suppresses the verbose startup output

The Code: Gemini Version

If you're using Google's Gemini CLI:

The _how_gemini Function

# how_gemini - Tell me the command (Gemini version)
_how_gemini() {
  if [[ -z "$*" ]]; then
    echo "Usage: how <what command do you need?>"
    return 1
  fi

  local result
  result=$(command gemini \
    "You are a command-line expert. Respond with ONLY the command - no \
explanation, no markdown. Question: $*" 2>/dev/null)

  # Gemini tends to wrap in backticks, strip them
  result=$(echo "$result" | tr -d '`')

  if [[ -n "$result" ]]; then
    echo "$result" | pbcopy
    echo "Command ready (also copied to clipboard):"
    print -z "$result"
  else
    echo "No result from Gemini"
    return 1
  fi
}

The _pls_gemini Function

# pls_gemini - Do this task (Gemini version)
_pls_gemini() {
  if [[ -z "$*" ]]; then
    echo "Usage: pls <what do you want me to do?>"
    return 1
  fi

  command gemini \
    "You are a helpful assistant. Perform this task and be concise: $*" 2>/dev/null
}

The Aliases

alias how_gemini='noglob _how_gemini'
alias pls_gemini='noglob _pls_gemini'
Gemini differences:
  • Simpler invocation - just pass the prompt as a positional argument
  • Gemini wraps responses in backticks more often, so we strip them
  • 2>/dev/null suppresses debug output

Why This Matters

The thing that makes agentic AI tools superpowered is that they know every bash command, every terminal utility, every combination of flags on the planet. That's a superpower.

At my terminal, I now have access to that superpower without: - Opening a full AI coding session - Leaving my current context - Breaking my flow - Waiting for an IDE to load

Key Takeaways

  1. You don't need an IDE for AI-assisted terminal work - Simple wrapper functions get you 80% of the value
  2. noglob is essential - It lets you type natural language without the shell mangling your input
  3. Separate "tell me" from "do it" - The how vs pls distinction keeps you in control
  4. Restrict tools for safety - The pls function only allows read operations
  5. AI knows every command - You shouldn't have to memorize obscure flags

These tiny quality-of-life improvements add up. I use these dozens of times a day, and they've completely eliminated my "what was that command again?" moments.

The scripts are available in my gopher-ai repo. Clone it, source the functions, and give your terminal superpowers.

Want more AI development insights?

Subscribe to the newsletter for weekly tips on using AI in professional development.

Subscribe to Newsletter

// KEEP READING

More articles