Skip to content

Adding Knobs and Switches

The difference between a good tool and a great tool? Options. Let's add --lang french and --format json to your toolkit.

What You'll Build

A flexible summarizer with adjustable length and style options.

Your First Flag

Let's add a --style flag to control how our summary sounds:

name: summarize
version: "1.0.0"
description: Summarize text with style

arguments:
  - flag: --style
    variable: style
    default: "concise"
    description: "Style: concise, detailed, or bullet-points"

steps:
  - type: prompt
    provider: claude
    prompt: |
      Summarize this in a {style} style:

      {input}
    output_var: summary

output: "{summary}"

Now you can run:

# Default (concise)
cat article.txt | summarize

# Detailed analysis
cat article.txt | summarize --style detailed

# Quick bullet points
cat article.txt | summarize --style bullet-points

Notice how the flag value flows right into {style} in the prompt. That's the magic.

Anatomy of an Argument

Every argument has four parts:

arguments:
  - flag: --style           # What users type
    variable: style         # Name in your templates
    default: "concise"      # Value when flag is omitted
    description: "How to write the summary"  # Help text

Pro Tip: The Golden Rule

Your tool should work perfectly with zero flags. Defaults are for the 80% case. Flags are for the other 20%.

Stacking Multiple Flags

Real tools need multiple options. Here's a translation tool with three knobs:

name: translate
version: "1.0.0"
description: Translate with control

arguments:
  - flag: --to
    variable: target_lang
    default: "Spanish"
    description: "Target language"

  - flag: --tone
    variable: tone
    default: "neutral"
    description: "Tone: casual, neutral, formal"

  - flag: --preserve
    variable: preserve
    default: "meaning"
    description: "Preserve: meaning, structure, or both"

steps:
  - type: prompt
    provider: claude
    prompt: |
      Translate to {target_lang}.
      Use a {tone} tone.
      Preserve the {preserve}.

      Text:
      {input}
    output_var: result

output: "{result}"

Now you have fine-grained control:

# Simple translation
cat email.txt | translate --to French

# Formal business translation
cat email.txt | translate --to Japanese --tone formal

# Technical translation preserving structure
cat docs.md | translate --to German --preserve structure

The Art of Good Flags

Do This

  • --lang not --target-language
  • --max not --maximum-length
  • --style not --s

Not This

  • -l (too cryptic)
  • --target_language (underscores feel wrong)
  • --TargetLanguage (this isn't Java)

The Numeric Gotcha

Warning: Quote Your Numbers!

YAML defaults are strings. Always quote numbers:

# WRONG - YAML might do weird things
default: 100

# RIGHT - Always a string
default: "100"

In your prompt, it'll work the same either way—but quoting prevents surprises.

Try It: Build a Code Reviewer

Exercise

Create a code review tool with these flags:

  • --focus - What to focus on (bugs, style, performance)
  • --severity - Minimum severity to report (low, medium, high)
See the solution
name: review
version: "1.0.0"
description: AI code review with focus

arguments:
  - flag: --focus
    variable: focus
    default: "bugs"
    description: "Focus: bugs, style, performance, security"

  - flag: --severity
    variable: severity
    default: "medium"
    description: "Minimum severity: low, medium, high"

steps:
  - type: prompt
    provider: claude
    prompt: |
      Review this code. Focus on {focus} issues.
      Only report issues of {severity} severity or higher.

      Code:
      {input}
    output_var: review

output: "{review}"

Next Up

You've mastered single-step tools with arguments. Ready for the real power?