struckdown

Struckdown CLI Usage Guide

Complete reference for the sd command-line interface.

Table of Contents


Installation

# Using uv (recommended)
uv tool install git+https://github.com/benwhalley/struckdown/

# Or install in current environment
uv pip install git+https://github.com/benwhalley/struckdown/

Environment Setup:

export LLM_API_KEY="your-api-key"          # e.g., from openai.com
export LLM_API_BASE="https://api.openai.com/v1"
export DEFAULT_LLM="litellm/gpt-4.1-mini"

Commands

sd chat

Run a single prompt interactively. Best for testing prompts and quick experiments.

Syntax:

sd chat [OPTIONS] PROMPT...

Options:

Examples:

# Simple completion
sd chat "Tell me a joke: [[joke]]"

# Multiple slots
sd chat "Name a color: [[pick:color|red,blue,green]] Describe it: [[description]]"

# With context display
sd chat "Pick a number: [[int:number]]" --show-context

sd batch

Process multiple inputs in batch mode. Supports files, globs, stdin, and chaining.

Syntax:

sd batch [OPTIONS] [INPUTS...] [PROMPT]

Arguments:

Input Sources:

  1. Files: sd batch file1.txt file2.txt "[[summary]]"
  2. Globs: sd batch inputs/*.txt "[[summary]]"
  3. Stdin: cat data.txt | sd batch "[[summary]]"
  4. JSON stdin: echo '{"name":"Alice"}' | sd batch "Hello [[greeting]]"

Output Formats:


Global Options

--help

Show help for any command.

sd --help
sd chat --help
sd batch --help

Output: stdout Exit code: 0


Batch Processing Options

-o / --output PATH

Output file path. Format auto-detected from extension.

sd batch *.txt "[[name]]" -o results.json   # JSON output
sd batch *.txt "[[name]]" -o results.csv    # CSV output
sd batch *.txt "[[name]]" -o results.xlsx   # Excel output
sd batch *.txt "[[name]]" -o results.md     # Markdown table

Default: Outputs JSON to stdout if omitted.


-p / --prompt PATH

Load prompt from file instead of inline.

# prompt.sd contains: "Extract name: [[name]]"
sd batch *.txt -p prompt.sd -o results.json

Cannot be combined with inline prompt.


-k / --keep-inputs

Include input fields in output (filename, content, basename).

sd batch *.txt "[[summary]]" -k -o results.json

Output includes:

{
  "filename": "input.txt",
  "input": "original text...",
  "content": "original text...",
  "basename": "input",
  "summary": "extracted summary"
}

Default: Only extracted fields + filename for traceability.


-q / --quiet

Suppress progress output to stderr.

sd batch *.txt "[[name]]" -o results.json --quiet

Behavior:

Use case: Scripting, cron jobs, CI/CD pipelines.


--verbose

Enable debug logging to stderr.

sd batch *.txt "[[name]]" --verbose 2> debug.log

Output includes:

Destination: stderr


--model-name TEXT

Override default LLM model for this run.

sd batch *.txt "[[summary]]" --model-name "litellm/gpt-4"

Default: $DEFAULT_LLM environment variable.


Progress Bars

sd batch shows a progress bar by default during processing:

Processing ⠋ ━━━━━━━━━━━━━━━━━━━━━━ 47/100 47% 0:00:23

Display includes:

Automatic Behavior

Shown when:

Hidden when:

Manual Control

# Force show (default in terminal)
sd batch *.txt "[[name]]" -o out.json

# Force hide
sd batch *.txt "[[name]]" -o out.json --quiet

# Redirect to ignore progress
sd batch *.txt "[[name]]" -o out.json 2>/dev/null

Output Streams

Struckdown follows CLI best practices for output streams:

stdout (File Descriptor 1)

Primary output - machine-readable results, intended for piping/capture.

Contains:

Example:

sd batch *.txt "[[name]]" > results.json   # Only results captured

stderr (File Descriptor 2)

Diagnostics - human-readable status, errors, warnings.

Contains:

Example:

sd batch *.txt "[[name]]" 2> errors.log    # Only diagnostics captured

Exit Codes

Code Meaning Examples
0 Success Command completed without errors
1 Error LLM failure, file not found, processing error
2 Usage error Invalid arguments, missing required options

Example:

sd batch --invalid-flag
# Exit code: 2 (usage error)

sd batch missing-file.txt "[[x]]"
# Exit code: 1 (file not found error)

sd batch *.txt "[[x]]" -o out.json
# Exit code: 0 (success)

Examples

Basic Batch Processing

Extract names from text files:

sd batch documents/*.txt "Extract person's name: [[name]]" -o names.json

Output:

[
  {"filename": "doc1.txt", "name": "Alice"},
  {"filename": "doc2.txt", "name": "Bob"}
]

Piping and Chaining

Chain multiple extraction steps:

sd batch *.txt "Purpose: [[purpose]] Name: [[name]]" | \
  sd batch ": . Amazon equivalent? [[product]]" -k

Process and filter with jq:

sd batch *.txt "Price: [[number:price]]" | jq '.[] | select(.price > 100)'

Quiet Mode for Scripts

Silent execution, log errors:

#!/bin/bash
sd batch data/*.txt "[[summary]]" -o results.json --quiet 2> errors.log

if [ $? -eq 0 ]; then
  echo "Processing complete: results.json"
else
  echo "Errors occurred, check errors.log"
  exit 1
fi

Verbose Debugging

Capture full debug output:

sd batch *.txt "[[name]]" --verbose 2> debug.log

Debug log contains:


Reading from Stdin

Plain text:

echo "Hello world" | sd batch "Translate to Spanish: [[translation]]"

JSON input:

echo '[{"name":"Alice"},{"name":"Bob"}]' | \
  sd batch "Hello ! [[greeting]]"

From file:

cat data.txt | sd batch "Summarize: [[summary]]" -o summary.json

Multiple Output Formats

CSV for spreadsheet import:

sd batch *.txt "Name: [[name]] Age: [[int:age]]" -o people.csv

Excel for reports:

sd batch *.txt "Product: [[product]] Price: [[number:price]]" -o report.xlsx

Markdown for documentation:

sd batch *.txt "Feature: [[feature]] Status: [[pick:status|done,wip,todo]]" -o status.md

Error Handling

Separate successful results and errors:

sd batch *.txt "[[summary]]" -o results.json 2> errors.log

# Check exit code
if [ $? -ne 0 ]; then
  echo "Some items failed, check errors.log"
fi

Verbose mode for debugging failures:

sd batch failing-input.txt "[[x]]" --verbose

Tips and Best Practices

Performance

Composability

Debugging

Scripting



Migration from chatter

The legacy chatter CLI has been removed in v0.1.6.

Old command:

chatter run "Tell me a joke: [[joke]]"

New command:

sd chat "Tell me a joke: [[joke]]"

Functionality is identical. All flags and options work the same way.