Skip to content

LLM CLI in 30 mins

  • TL;DR: llm_cli is a lightweight CLI tool that applies LLM transformations to text and code files. Use it to refactor code, improve docs, apply linting rules, or run custom prompts on file chunks — all from shell without leaving editor

Introduction#

  • Text transformation is a common dev task: refactoring code, improving docs, fixing style issues, applying rules to slide decks, generating summaries
  • llm_cli automates this: pipe text through LLM directly from shell

  • llm_cli solves several problems:

  • Apply LLM transformations without leaving terminal
  • Use system prompts, rules, or skills to guide LLM behavior
  • Process specific file chunks without touching the rest
  • Chain transformations in shell pipelines
  • Auto-lint output with Prettier

  • Unlike generic LLM wrappers, llm_cli integrates with Claude Code skills and rules: apply same transformations from command line as from IDE

When to Use It#

  • Use llm_cli when you need to:
  • Refactor multiple files with same rules
  • Apply a skill (e.g., "fix documentation" or "improve code style") to a file
  • Extract a file section, transform with LLM, and reassemble original
  • Integrate LLM transformations into shell scripts or Makefiles
  • Test a prompt or rule before applying via Claude Code

  • Similar tools are

  • llm CLI (Simon Willison)
  • ChatGPT
  • one-off Python scripts but none combine LLM + file handling + rule integration as cleanly

Prerequisites#

  • Python 3.11 or later
  • Access to LLM API (OpenAI, Anthropic, or OpenRouter)
  • llm Python library installed (auto-included in helpers)
  • .claude/skills/ dir with skill definitions (optional, but useful)

Installation and Setup#

  • llm_cli comes with helpers library. Verify it's available:

    > llm_cli.py --help
    usage: llm_cli.py [-h] [--input INPUT] [--input_text INPUT_TEXT] ...
    
  • Configure LLM API key:

    > export OPENAI_API_KEY="your-key-here"
    
  • Or for Claude via Anthropic:

    > export ANTHROPIC_API_KEY="your-key-here"
    
  • Check that LLM is working:

    > llm_cli.py --input_text "Say hello" --output -
    Hello! How can I help you today?
    

Core Concepts#

  • llm_cli operates in these stages:
  • Read input: From file, stdin, or directly as text
  • Extract chunk (optional): Use --select to process only part of file
  • Choose a prompt: Inline prompt, file, rule from .claude/skills/, or full skill
  • Transform: Send text through LLM
  • Optionally lint: Auto-format output (e.g., with Prettier)
  • Write output: To file, stdout, or back to input file

  • Each stage optional depending on use case. Simplest usage: input and output

Key Options#

  • --input FILE / -i FILE: Input file path. Use - for stdin
  • --input_text TEXT: Input text from command line
  • --output FILE / -o FILE: Output file path. Use - for stdout
  • --system_prompt TEXT / -p TEXT: Prompt text to guide the LLM
  • --system_prompt_file FILE / -pf FILE: Read prompt from file
  • --rule SPEC: Extract a rule from .claude/skills/topic.rules.md
  • --skill NAME: Use a skill's full SKILL.md file as prompt
  • --select SPEC: Process only lines matching a selection spec
  • --lint: Auto-format output with Prettier
  • --model MODEL: Which LLM to use (default: gpt-4)
  • --modify_in_place / -m: Edit file in place instead of creating new one

Hands-On Examples#

Example 1: Basic Text Transformation#

  • Start with simplest case: transform input text and print result

  • Create a sample file:

> cat > input.txt << 'EOF'
The quick brown fox jumps over the lazy dog.
It was a dark and stormy night.
The hero entered the room with caution.
EOF
  • Transform with a simple prompt:
> llm_cli.py -i input.txt -o - --system_prompt "Rewrite this in one sentence"
The quick brown fox leaped over a lazy dog during a dark, stormy night as the cautious hero entered the room.
  • -o - prints to stdout instead of writing to file

Example 2: Edit a File in Place#

  • Process a file and save result back to itself:
> llm_cli.py -i input.txt --system_prompt "Make this more formal" -m
  • Check result:
> cat input.txt
A swift, auburn canine traversed an obstacle formed by a sluggish animal.
It was an exceptionally dark evening accompanied by severe meteorological conditions.
The protagonist proceeded cautiously into the chamber.
  • -m flag modifies file in place without separate output file

Example 3: Apply a Skill From Claude Code#

  • If you have a skill in .claude/skills/, apply it directly:
> llm_cli.py -i code.py --skill coding.fix_docstring -m
  • This applies entire coding.fix_docstring skill to your file
  • Skills more powerful than inline prompts: contain detailed instructions and examples

Example 4: Transform Only Part of a File#

  • Extract a chunk, transform it, reassemble. Useful when only specific lines need changes

  • Create a sample file with markers:

> cat > slides.txt << 'EOF'
## Slide 1: Introduction

This is a basic intro slide.
It needs better content.

## Slide 2: Main Topic

The main point is important.
But unclear.

## Slide 3: Conclusion

Wrap up the presentation.
Make it memorable.
EOF
  • Transform only Slide 2 using line numbers:
> llm_cli.py -i slides.txt --select 6:8 --system_prompt "Improve clarity" -m
  • --select 6:8 processes only lines 6-8, leaving rest untouched

Example 5: Apply a Rule with Auto-Linting#

  • Rules are snippets from a skill file. Extract one and apply with auto-formatting:
> llm_cli.py -i README.md --rule '.claude/skills/markdown.rules.md:42:# Fix Bold Labels' --lint -m
  • Rule specified as file:line_number:rule_name. --lint runs Prettier on output for consistent formatting

Tips and Gotchas#

Tip 1: Use Pipes for Chaining#

  • llm_cli integrates with Unix pipes: transform output from one tool into input for another
> cat raw_notes.txt | llm_cli.py -i - -o - --system_prompt "Summarize in 3 bullet points"

Tip 2: Estimate Output Size for Large Files#

  • By default, llm_cli shows a progress bar but doesn't know output size
  • Help it:
> llm_cli.py -i large_file.py --system_prompt "Add type hints" --expected_num_chars 50000
  • Or let it auto-estimate:
> llm_cli.py -i large_file.py --system_prompt "Add type hints" --progress_bar

Tip 3: Use Dry-Run to Preview#

  • Before modifying files, dry-run to see what would happen:
> llm_cli.py -i important_file.py --system_prompt "Refactor" --dry_run
  • Shows LLM params without calling API or modifying files

Gotcha 1: Stdin Requires Output Specification#

  • When reading from stdin with -i -, must specify an output:
> echo "text" | llm_cli.py -i - -o output.txt  # OK
> echo "text" | llm_cli.py -i -                 # ERROR
  • Use -o - to print to stdout:
> echo "text" | llm_cli.py -i - -o -

Gotcha 2: Only One Prompt Option at a Time#

  • Use -p (inline), -pf (from file), --rule (from rules), or --skill (full skill), not multiple:
> llm_cli.py -i file.txt -p "Fix it" --rule '.claude/skills/my.rules.md:10:Rule'  # ERROR

Gotcha 3: Linting Only Works with Markdown#

  • --lint flag currently formats output as Markdown with Prettier. If working with code files, linting won't apply:
> llm_cli.py -i code.py --system_prompt "Add comments" --lint  # Linting won't affect Python

Next Steps#

  • Read full docs in dev_scripts_helpers/llms/README.md
  • Explore existing skills in .claude/skills/ to see available transformations
  • Create custom rule for repetitive tasks (e.g., "Fix grammar in slide decks")
  • Integrate llm_cli into Makefile or shell script for batch processing
  • Experiment with different models using --model openrouter/anthropic/claude-opus-4.6

Advanced: Combining with Other Tools#

  • Use llm_cli alongside other helpers:
  • Refactor code and run tests:

    > llm_cli.py -i module.py --system_prompt "Refactor for readability" -m && python -m pytest module_test.py
    
  • Fix a specific function in a file:

    > llm_cli.py -i file.py --select "def my_func" --skill coding.fix_docstring -m
    
  • Process multiple files in a loop:

    > for file in *.md; do llm_cli.py -i "$file" --skill markdown.fix_bullet_points -m; done
    
  • llm_cli bridges terminal and LLM capabilities. Use it whenever you write manual prompts to fix or improve text: that's a sign the transformation should be automated