# Example Tools

This document contains all 28 pre-built SmartTools with their full configurations.

## Quick Install

```bash
# Install all example tools (from the SmartTools directory)
python examples/install.py
smarttools refresh
```

## Text Processing Tools

### summarize

Condense long documents to key points.

```yaml
# ~/.smarttools/summarize/config.yaml
name: summarize
description: Condense long documents to key points
arguments:
  - flag: --length
    variable: length
    default: "3-5 bullet points"
steps:
  - type: prompt
    prompt: |
      Summarize the following text into {length}. Be concise and capture the key points:

      {input}
    provider: opencode-pickle
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat article.txt | summarize
cat book.txt | summarize --length "10 bullet points"
```

---

### translate

Translate text to any language.

```yaml
name: translate
description: Translate text to any language
arguments:
  - flag: --lang
    variable: lang
    default: Spanish
steps:
  - type: prompt
    prompt: |
      Translate the following text to {lang}. Only output the translation, nothing else:

      {input}
    provider: claude-haiku
    output_var: response
output: "{response}"
```

**Usage:**
```bash
echo "Hello, world!" | translate --lang French
cat readme.md | translate --lang Japanese
```

---

### fix-grammar

Fix grammar and spelling errors.

```yaml
name: fix-grammar
description: Fix grammar and spelling errors
arguments: []
steps:
  - type: prompt
    prompt: |
      Fix all grammar, spelling, and punctuation errors in the following text. Only output the corrected text, no explanations:

      {input}
    provider: opencode-deepseek
    output_var: response
output: "{response}"
```

**Usage:**
```bash
echo "teh cat sat on teh mat" | fix-grammar
cat draft.txt | fix-grammar > fixed.txt
```

---

### simplify

Rewrite text for easier understanding.

```yaml
name: simplify
description: Rewrite text for easier understanding
arguments:
  - flag: --level
    variable: level
    default: "5th grade reading level"
steps:
  - type: prompt
    prompt: |
      Rewrite the following text for a {level}. Keep the meaning but use simpler words and shorter sentences:

      {input}
    provider: opencode-pickle
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat legal_document.txt | simplify
cat technical.md | simplify --level "non-technical reader"
```

---

### tone-shift

Change the tone of text.

```yaml
name: tone-shift
description: Change the tone of text
arguments:
  - flag: --tone
    variable: tone
    default: professional
steps:
  - type: prompt
    prompt: |
      Rewrite the following text in a {tone} tone. Keep the core message but adjust the style:

      {input}
    provider: opencode-deepseek
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat angry_email.txt | tone-shift --tone "calm and professional"
cat casual_note.txt | tone-shift --tone formal
```

---

### eli5

Explain like I'm 5.

```yaml
name: eli5
description: Explain like I'm 5
arguments: []
steps:
  - type: prompt
    prompt: |
      Explain this like I'm 5 years old. Use simple words and fun analogies:

      {input}
    provider: opencode-pickle
    output_var: response
output: "{response}"
```

**Usage:**
```bash
echo "What is quantum computing?" | eli5
cat whitepaper.txt | eli5
```

---

### tldr

One-line summary.

```yaml
name: tldr
description: One-line summary
arguments: []
steps:
  - type: prompt
    prompt: |
      Give a one-line TL;DR summary of this text:

      {input}
    provider: opencode-grok
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat long_article.txt | tldr
curl -s https://example.com | tldr
```

---

### expand

Expand bullet points to paragraphs.

```yaml
name: expand
description: Expand bullet points to paragraphs
arguments: []
steps:
  - type: prompt
    prompt: |
      Expand these bullet points into well-written paragraphs:

      {input}
    provider: opencode-pickle
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat notes.txt | expand
echo "- Fast\n- Reliable\n- Easy to use" | expand
```

---

## Developer Tools

### explain-error

Explain error messages and stack traces.

```yaml
name: explain-error
description: Explain error messages and stack traces
arguments: []
steps:
  - type: prompt
    prompt: |
      Explain this error/stack trace in plain English. What went wrong and how to fix it:

      {input}
    provider: claude-haiku
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat error.log | explain-error
python script.py 2>&1 | explain-error
```

---

### explain-code

Explain what code does.

```yaml
name: explain-code
description: Explain what code does
arguments:
  - flag: --detail
    variable: detail
    default: moderate
steps:
  - type: prompt
    prompt: |
      Explain what this code does at a {detail} level of detail:

      ```
      {input}
      ```
    provider: opencode-pickle
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat script.py | explain-code
cat complex.js | explain-code --detail "very detailed"
```

---

### review-code

Quick code review with suggestions.

```yaml
name: review-code
description: Quick code review with suggestions
arguments:
  - flag: --focus
    variable: focus
    default: "bugs, security, and improvements"
steps:
  - type: prompt
    prompt: |
      Review this code focusing on {focus}. Be concise and actionable:

      ```
      {input}
      ```
    provider: claude-sonnet
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat pull_request.diff | review-code
cat auth.py | review-code --focus "security vulnerabilities"
```

---

### gen-tests

Generate unit tests for code.

```yaml
name: gen-tests
description: Generate unit tests for code
arguments:
  - flag: --framework
    variable: framework
    default: pytest
steps:
  - type: prompt
    prompt: |
      Generate comprehensive unit tests for this code using {framework}. Include edge cases:

      ```
      {input}
      ```
    provider: claude-haiku
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat utils.py | gen-tests
cat api.js | gen-tests --framework jest
```

---

### docstring

Add docstrings to functions/classes.

```yaml
name: docstring
description: Add docstrings to functions/classes
arguments:
  - flag: --style
    variable: style
    default: Google style
steps:
  - type: prompt
    prompt: |
      Add {style} docstrings to all functions and classes in this code. Output the complete code with docstrings:

      ```
      {input}
      ```
    provider: opencode-deepseek
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat module.py | docstring
cat functions.py | docstring --style "NumPy style"
```

---

### commit-msg

Generate commit message from diff.

```yaml
name: commit-msg
description: Generate commit message from diff
arguments:
  - flag: --style
    variable: style
    default: conventional commits
steps:
  - type: prompt
    prompt: |
      Generate a concise {style} commit message for this diff. Just the message, no explanation:

      {input}
    provider: opencode-pickle
    output_var: response
output: "{response}"
```

**Usage:**
```bash
git diff --staged | commit-msg
git diff HEAD~1 | commit-msg --style "simple"
```

---

## Data Tools

### json-extract

Extract structured data as validated JSON.

```yaml
name: json-extract
description: Extract structured data as validated JSON
arguments:
  - flag: --fields
    variable: fields
    default: any relevant fields
steps:
  - type: prompt
    prompt: |
      Extract {fields} from this text as a JSON object. Output ONLY valid JSON, no markdown, no explanation:

      {input}
    provider: opencode-deepseek
    output_var: raw_json
  - type: code
    code: |
      import json
      import re
      text = raw_json.strip()
      text = re.sub(r'^```json?\s*', '', text)
      text = re.sub(r'\s*```$', '', text)
      try:
          parsed = json.loads(text)
          validated = json.dumps(parsed, indent=2)
      except json.JSONDecodeError as e:
          validated = f"ERROR: Invalid JSON - {e}\nRaw output: {text[:500]}"
    output_var: validated
output: "{validated}"
```

**Usage:**
```bash
echo "Price $49.99, SKU ABC-123" | json-extract --fields "price, sku"
cat invoice.txt | json-extract --fields "total, date, items"
```

---

### json2csv

Convert JSON to CSV format.

```yaml
name: json2csv
description: Convert JSON to CSV format
arguments: []
steps:
  - type: prompt
    prompt: |
      Convert this JSON to CSV format. Output only the CSV, no explanation:

      {input}
    provider: opencode-deepseek
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat data.json | json2csv
echo '[{"name":"John","age":30}]' | json2csv
```

---

### extract-emails

Extract email addresses from text.

```yaml
name: extract-emails
description: Extract email addresses from text
arguments: []
steps:
  - type: prompt
    prompt: |
      Extract all email addresses from this text. Output one email per line, nothing else:

      {input}
    provider: opencode-pickle
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat webpage.html | extract-emails
cat contacts.txt | extract-emails | sort -u
```

---

### extract-contacts

Extract contact info as structured CSV.

```yaml
name: extract-contacts
description: Extract contact info as structured CSV
arguments: []
steps:
  - type: prompt
    prompt: |
      Extract all contact information (name, email, phone, company) from this text. Output as JSON array with objects having keys: name, email, phone, company. Use null for missing fields. Output ONLY the JSON array:

      {input}
    provider: opencode-pickle
    output_var: contacts_json
  - type: code
    code: |
      import json
      import re
      text = contacts_json.strip()
      text = re.sub(r'^```json?\s*', '', text)
      text = re.sub(r'\s*```$', '', text)
      try:
          contacts = json.loads(text)
          lines = ['name,email,phone,company']
          for c in contacts:
              row = [
                  str(c.get('name') or ''),
                  str(c.get('email') or ''),
                  str(c.get('phone') or ''),
                  str(c.get('company') or '')
              ]
              lines.append(','.join(f'"{f}"' for f in row))
          csv_output = '\n'.join(lines)
      except:
          csv_output = f"Error parsing contacts: {text[:200]}"
    output_var: csv_output
output: "{csv_output}"
```

**Usage:**
```bash
cat business_cards.txt | extract-contacts
cat meeting_notes.txt | extract-contacts > contacts.csv
```

---

### sql-from-text

Generate SQL from natural language.

```yaml
name: sql-from-text
description: Generate SQL from natural language
arguments:
  - flag: --dialect
    variable: dialect
    default: PostgreSQL
steps:
  - type: prompt
    prompt: |
      Generate a {dialect} SQL query for this request. Output only the SQL, no explanation:

      {input}
    provider: claude-haiku
    output_var: response
output: "{response}"
```

**Usage:**
```bash
echo "get all users who signed up last month" | sql-from-text
echo "count orders by status" | sql-from-text --dialect MySQL
```

---

### safe-sql

Generate SQL with safety checks.

```yaml
name: safe-sql
description: Generate SQL with safety checks
arguments:
  - flag: --dialect
    variable: dialect
    default: PostgreSQL
steps:
  - type: prompt
    prompt: |
      Generate a {dialect} SELECT query for: {input}

      Output ONLY the SQL query, no explanation.
    provider: claude-haiku
    output_var: raw_sql
  - type: code
    code: |
      import re
      sql = raw_sql.strip()
      sql = re.sub(r'^```sql?\s*', '', sql)
      sql = re.sub(r'\s*```$', '', sql)
      dangerous = ['DROP', 'DELETE', 'TRUNCATE', 'UPDATE', 'INSERT', 'ALTER', 'CREATE', 'GRANT']
      warnings = []
      for keyword in dangerous:
          if re.search(r'\b' + keyword + r'\b', sql, re.I):
              warnings.append(f"WARNING: Contains {keyword}")
      if warnings:
          validated = '\n'.join(warnings) + '\n\n' + sql
      else:
          validated = sql
    output_var: validated
output: "{validated}"
```

**Usage:**
```bash
echo "get active users" | safe-sql
echo "remove inactive accounts" | safe-sql  # Will show WARNING
```

---

### parse-log

Summarize and analyze log files.

```yaml
name: parse-log
description: Summarize and analyze log files
arguments:
  - flag: --focus
    variable: focus
    default: errors and warnings
steps:
  - type: prompt
    prompt: |
      Analyze these logs focusing on {focus}. Summarize key issues and patterns:

      {input}
    provider: claude-haiku
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat app.log | parse-log
tail -1000 /var/log/syslog | parse-log --focus "security events"
```

---

### csv-insights

Analyze CSV with sampled data for large files.

```yaml
name: csv-insights
description: Analyze CSV with sampled data for large files
arguments:
  - flag: --question
    variable: question
    default: What patterns and insights can you find?
steps:
  - type: code
    code: |
      import random
      lines = input.strip().split('\n')
      header = lines[0] if lines else ''
      data_lines = lines[1:] if len(lines) > 1 else []

      if len(data_lines) > 50:
          sampled = random.sample(data_lines, 50)
          sample_note = f"(Sampled 50 of {len(data_lines)} rows)"
      else:
          sampled = data_lines
          sample_note = f"({len(data_lines)} rows)"

      sampled_csv = header + '\n' + '\n'.join(sampled)
      stats = f"Columns: {len(header.split(','))}, Rows: {len(data_lines)} {sample_note}"
    output_var: sampled_csv,stats
  - type: prompt
    prompt: |
      Analyze this CSV data. {stats}

      Question: {question}

      Data:
      {sampled_csv}
    provider: claude-haiku
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat sales.csv | csv-insights
cat large_data.csv | csv-insights --question "What are the top trends?"
```

---

## Advanced Multi-Step Tools

### log-errors

Extract and explain errors from large log files.

```yaml
name: log-errors
description: Extract and explain errors from large log files
arguments: []
steps:
  - type: code
    code: |
      import re
      lines = input.split('\n')
      errors = [l for l in lines if re.search(r'\b(ERROR|CRITICAL|FATAL|Exception|Traceback)\b', l, re.I)]
      result = []
      for i, line in enumerate(lines):
          if re.search(r'\b(ERROR|CRITICAL|FATAL|Exception|Traceback)\b', line, re.I):
              result.extend(lines[i:i+5])
      extracted = '\n'.join(result[:200])
    output_var: extracted
  - type: prompt
    prompt: |
      Analyze these error log entries. Group by error type, explain likely causes, and suggest fixes:

      {extracted}
    provider: claude-haiku
    output_var: response
output: "{response}"
```

**Usage:**
```bash
cat huge_app.log | log-errors
zcat archived.log.gz | log-errors
```

---

### diff-focus

Review only the added/changed code in a diff.

```yaml
name: diff-focus
description: Review only the added/changed code in a diff
arguments: []
steps:
  - type: code
    code: |
      lines = input.split('\n')
      result = []
      for i, line in enumerate(lines):
          if line.startswith('@@') or line.startswith('+++') or line.startswith('---'):
              result.append(line)
          elif line.startswith('+') and not line.startswith('+++'):
              result.append(line)
      extracted = '\n'.join(result)
    output_var: extracted
  - type: prompt
    prompt: |
      Review these added lines of code. Focus on bugs, security issues, and improvements:

      {extracted}
    provider: claude-haiku
    output_var: response
output: "{response}"
```

**Usage:**
```bash
git diff | diff-focus
git diff HEAD~5 | diff-focus
```

---

### changelog

Generate changelog from git commits.

```yaml
name: changelog
description: Generate changelog from git commits
arguments:
  - flag: --since
    variable: since
    default: last week
steps:
  - type: code
    code: |
      lines = input.strip().split('\n')
      commits = []
      for line in lines:
          if line.strip() and not line.startswith('commit '):
              commits.append(line.strip())
      git_log = '\n'.join(commits[:100])
    output_var: git_log
  - type: prompt
    prompt: |
      Generate a user-friendly changelog from these git commits. Group by category (Features, Fixes, Improvements, etc). Use markdown with bullet points:

      {git_log}
    provider: opencode-pickle
    output_var: changelog_raw
  - type: code
    code: |
      from datetime import datetime
      header = f"""# Changelog

Generated: {datetime.now().strftime('%Y-%m-%d')}

"""
      formatted = header + changelog_raw
    output_var: formatted
output: "{formatted}"
```

**Usage:**
```bash
git log --oneline -50 | changelog
git log --since="2024-01-01" --oneline | changelog
```

---

### code-validate

Generate and validate Python code.

```yaml
name: code-validate
description: Generate and validate Python code
arguments:
  - flag: --task
    variable: task
    default: ""
steps:
  - type: prompt
    prompt: |
      Write Python code to: {task}

      Context/input data:
      {input}

      Output ONLY the Python code, no markdown, no explanation.
    provider: claude-haiku
    output_var: raw_code
  - type: code
    code: |
      import ast
      import re
      code = raw_code.strip()
      code = re.sub(r'^```python?\s*', '', code)
      code = re.sub(r'\s*```$', '', code)
      try:
          ast.parse(code)
          validated = code
      except SyntaxError as e:
          validated = f"# SYNTAX ERROR at line {e.lineno}: {e.msg}\n# Fix needed:\n\n{code}"
    output_var: validated
output: "{validated}"
```

**Usage:**
```bash
echo "list of numbers: 1,2,3,4,5" | code-validate --task "calculate the sum"
cat data.json | code-validate --task "parse and find the maximum value"
```

---

## Writing Your Own Tools

### Basic Structure

```yaml
name: my-tool
description: What this tool does
arguments:
  - flag: --option
    variable: option_name
    default: "default value"
steps:
  - type: prompt
    prompt: |
      Your prompt here with {input} and {option_name}
    provider: opencode-pickle
    output_var: response
output: "{response}"
```

### Multi-Step Structure

```yaml
name: my-pipeline
description: Multi-step tool
steps:
  # Step 1: Preprocess with code
  - type: code
    code: |
      # Python code here
      processed = input.upper()
    output_var: processed

  # Step 2: AI processing
  - type: prompt
    prompt: "Analyze: {processed}"
    provider: claude-haiku
    output_var: analysis

  # Step 3: Post-process with code
  - type: code
    code: |
      result = f"RESULT:\n{analysis}"
    output_var: result
output: "{result}"
```

### Tips

1. **Use cheap providers** for simple tasks (`opencode-pickle`)
2. **Use code steps** to validate AI output
3. **Preprocess large inputs** to reduce tokens
4. **Test with mock** before using real AI: `--provider mock`

---

## Pipeline Recipes

SmartTools chain together like Unix commands. Here are practical examples:

### Development Workflows

```bash
# Quick PR review: extract changes, review, summarize
git diff main | diff-focus | review-code --focus "bugs and security" | tldr

# Explain and fix an error in one pipeline
python script.py 2>&1 | explain-error | tee error_analysis.txt

# Generate tests for changed files only
git diff --name-only | grep '\.py$' | xargs cat | gen-tests > new_tests.py

# Create release notes from commits
git log v1.0..v1.1 --oneline | changelog | translate --lang French > RELEASE_FR.md
```

### Data Processing

```bash
# Extract, transform, analyze
curl -s api.example.com/data | json-extract --fields "users, revenue" | json2csv | csv-insights

# Process multiple files
for f in reports/*.txt; do
    cat "$f" | json-extract --fields "total, date"
done | json2csv > summary.csv

# Clean and deduplicate contacts
cat *.vcf | extract-contacts | sort -u -t',' -k2 > contacts.csv
```

### Text Processing Pipelines

```bash
# Translate technical docs for international team
cat API.md | simplify --level "non-technical" | translate --lang Spanish > API_ES.md

# Process customer feedback
cat feedback.txt | summarize --length "10 points" | tone-shift --tone analytical | json-extract --fields "themes, sentiment"

# Prepare content for different audiences
cat whitepaper.txt | eli5 > simple_version.txt
cat whitepaper.txt | summarize > executive_summary.txt
```

### Shell Functions

Add these to `~/.bashrc` for common workflows:

```bash
# Review recent changes
review-recent() {
    git diff HEAD~"${1:-1}" | diff-focus | review-code | tldr
}

# Quick translate with summary
translate-summary() {
    cat "$1" | summarize | translate --lang "${2:-Spanish}"
}

# Analyze any log file
analyze-log() {
    cat "$1" | log-errors | summarize --length "5 key issues"
}

# Generate commit message and commit
auto-commit() {
    msg=$(git diff --staged | commit-msg)
    echo "Commit message: $msg"
    read -p "Commit? [y/N] " confirm
    [[ $confirm == [yY] ]] && git commit -m "$msg"
}
```

### Combining with Standard Unix Tools

```bash
# Filter before AI processing (saves tokens)
cat huge.log | grep -i error | tail -100 | explain-error

# Post-process AI output
cat doc.txt | summarize | fmt -w 80 > formatted_summary.txt

# Parallel processing
find . -name "*.py" | parallel -j4 'cat {} | review-code > {}.review'

# Watch and process
tail -f app.log | grep --line-buffered ERROR | while read line; do
    echo "$line" | explain-error
done
```
