# spooligan: a guide for AI agents

This is the core guide for driving `spooligan` from a terminal. `spooligan agents` prints it and it ships next to
the binary, so it always matches the version you run. The details are in topics built into the binary:
`spooligan agents TOPIC` prints one, `spooligan agents --list` lists them, and `spooligan agents --all` prints this
guide followed by every topic. [Topics](#topics) says which to read when.

## Quick start

```sh
spooligan agents                           # this guide
spooligan note "Back in 5" -o note.png     # render to a picture; nothing is printed
spooligan print day.yaml -o day.png        # render a document you wrote
spooligan validate day.yaml --json         # every mistake at once, with paths and line numbers
spooligan printer list                     # the printers set up on this machine
spooligan print day.yaml                   # print on the default printer, only when the user asks
```

Five rules cover most of the work:

1. **Print only when the user asks you to, and then print what they asked for.** Without `-o` or `-n`, every print
   command sends out paper. There is no need to show a preview first.
2. **Preview when it helps:** when the user wants to see the receipt first, or you aren't sure how it will come out.
   `-o FILE.png` writes the receipt as a picture and never touches a printer.
3. **Write a document** (YAML or JSON with a list of blocks) for anything beyond one line. `spooligan blocks` lists
   the block types and `spooligan blocks TYPE` shows one type's fields.
4. **Add `--json`** when you parse the output, and check the exit code: 0 is success.
5. **Don't change printer settings.** See [Safety rules](#safety-rules).

**No printer? Everything but printing still works.** Rendering needs no printer and no config, not even
`spooligan init` or `printer setup`: `-o FILE.png` works on a fresh machine, and so do `preview`, `demo all -o DIR`,
`validate` and `studio`. That makes spooligan useful on its own for designing receipts or making pictures of them.
A print without `-o` exits 3 with "no printer set up"; when that happens, show the PNG instead, and suggest
`spooligan printer setup` only if the user has a USB printer they want to use.

## Safety rules

- **Looking never prints.** `-o FILE.png` writes a picture, `-o FILE.bin` writes the ESC/POS bytes, and `-n`
  (`--dry-run`) renders and checks without writing anything. None of them contact a printer.
- **Never print unless the user asked for a print.** These commands print by default: `print`, every template
  shortcut (`note`, `list`, `todo`, ...), a file or template name given as the command, `hello`, `demo NAME`,
  `demo all`, `printer test` and `printer send`. Give them `-o` or `-n` when you only want to look.
- **Use the printer the user means.** `spooligan printer list` shows the default (marked `*`); `-P NAME` picks
  another.
- **Ask before changing settings that last.** `spooligan printer setup`, `spooligan init` and edits to a
  `config.yaml` change what later prints do: run them only when the user agrees.
- **Settings writes need the user's explicit yes.** `spooligan printer buzzer off|on` is the only command that changes
  a setting stored in a printer, and it works on one model only (NETUM NT-861). Run it only when the user asks for
  exactly that: show the bytes first (`printer buzzer off NAME -n`), get an explicit yes, then run it. Afterwards the
  user must turn the printer off and on again. Don't add `--yes` or `--force` on your own.
- **Never send speed, density or other settings commands** to a printer, for example with `printer send` on a file
  you made by hand. Many thermal printers misbehave after them until they are power-cycled. `printer send` is for
  `.bin` files that `spooligan ... -o FILE.bin` wrote; it refuses a file holding such commands, and `--force`
  overrides that only on the user's explicit word.
- **Mind the length.** Over 1 m a receipt gets a warning; over 3 m spooligan prints only with `--force`. A receipt
  that long is usually a mistake (a huge list or a repeated block): show the user the PNG and ask.
- **`studio --lan` opens the editor to the whole network.** Use it only when the user asks.
- **Updates are the user's call.** `spooligan update --check` and `spooligan update -n` only read and are fine to run
  (exit 10: a newer release is out; tell the user). Never run `spooligan update` or `spooligan update --rollback`
  without the user's explicit OK: they replace the binary, and may ask for a password. At a terminal, spooligan may
  add a daily "Spooligan X is available" notice on stderr; it never appears in `--json` output or pipes, so don't
  parse for it. `SPOOLIGAN_NO_UPDATE_CHECK=1` turns it off.

## What spooligan is

`spooligan` is one self-contained executable that prints receipts on ESC/POS thermal printers, 80 mm or 58 mm wide.
It needs no runtime, no drivers and no internet connection: the fonts and icons are built in.

The mental model:

1. **Input.** A **document** is a YAML or JSON file with a list of **blocks**: a header, a checklist, a table, a QR
   code, a picture. A **template** is a document with parameters, such as `note`, `list` or `packing_slip`; the
   shortcuts (`spooligan note "Back in 5"`) fill a built-in template from the command line. Plain text on stdin
   prints as a paragraph.
2. **Layout.** The blocks stack top to bottom into one picture exactly as wide as the paper: 576 dots at 80 mm, 384
   dots at 58 mm (8 dots per millimetre). A **style** (`modern` or `handwritten`) sets the fonts and the look; a
   language (`lang`) sets the built-in labels and dates.
3. **Output.** The picture is turned into black and white and either written to a file (`-o FILE.png`, or
   `-o FILE.bin` for the printer bytes) or sent to a printer as an ESC/POS raster image (`GS v 0`), then cut. The
   printer's own fonts are never used, so any layout, language or picture prints the same on every printer.
4. **Config.** Printers and defaults live in YAML config files, in layers: flags, environment variables, a project
   folder, a global folder and built-in defaults.

A PNG from `-o` is the receipt dot for dot: what you see is what prints.

## Install and connect a printer

Install it globally, as the `spooligan` command on the `PATH`: on macOS, the `Spooligan-VERSION.pkg` installer puts it
in `/usr/local/bin`; otherwise put the build for the system (`spooligan-macos-universal`, `spooligan-linux-amd64`,
`spooligan-linux-arm64`, `spooligan-windows-amd64.exe` and others) there as `spooligan` (`spooligan.exe` on Windows).
This guide is built into the binary, so `spooligan agents` prints it on any machine. `spooligan agents install`
covers every build, the macOS installer and zip, Linux USB permissions and Windows.

```sh
spooligan version
spooligan printer setup             # find the USB receipt printer and save it as the default (ask first)
spooligan printer list --scan       # the configured printers, and the ids of USB printers
spooligan init                      # a commented ~/.config/spooligan/config.yaml to fill in; never overwrites
spooligan config doctor             # check the config without contacting a printer
```

A printer is an entry under `printers:` in a config file, and `printer:` names the default:

```yaml
# file: ~/.config/spooligan/config.yaml
printer: desk
printers:
  desk: {type: usb, vendor_id: 0x0483, product_id: 0x5840}     # the ids from printer list --scan
  kitchen: {type: network, host: 192.0.2.40, paper: 58}        # raw TCP on port 9100
```

The types are `usb`, `network`, `serial`, `cups` and `file`; `paper: 58` marks a 58 mm printer.
`spooligan agents printers` has every field, the config layers and how to find a printer.

## Main commands

| Command | What it does |
| --- | --- |
| `spooligan print SRC [-o FILE]` | Print a document, a template file or a template name (`-` is stdin), or write a `.png` or `.bin` |
| `spooligan preview SRC` | Write `NAME.png`; never prints |
| `spooligan validate SRC... [--json]` | Check documents and templates; exit 2 if any is invalid |
| `spooligan note TEXT [key=value]`, and a shortcut for each template | Fill a built-in template and print it (see below); add `-o` to look first |
| `spooligan blocks [TYPE]` | The block types, or one type's fields and an example |
| `spooligan templates` and `spooligan templates show NAME` | The templates, or one template's params and examples |
| `spooligan printer list` and `spooligan printer status [NAME]` | The printers, or whether one is ready |
| `spooligan config which [KEY]` and `spooligan config doctor` | Where each setting comes from; check the config |
| `spooligan studio [FILE]` | A receipt editor in the browser: for "let me tweak it by hand", open the file there for the user (see `agents studio`) |
| `spooligan COMMAND --help` | One command's usage; runs nothing |

Common flags: `-o FILE` (`.png` or `.bin`), `-n` (render and check, write nothing), `-P NAME` (the printer), `-p 58`
(the paper), `-s hand` (the handwritten style), `-l TAG` (the language), `-d FILE` (template params from YAML or
JSON) and `--json`. Any other `--key value` is a template param. `spooligan agents commands` lists every command and
flag.

## What to print, and how

Each built-in template is also a command. Bare words fill its main param; `key=value` or `--key value` sets the
others, and `spooligan templates show NAME` lists them with ready examples (`spooligan preview NAME --example EX`).

| To print | Example |
| --- | --- |
| A sign or note | `spooligan note "Back in 5" --alert -o note.png` (or `--door`, `--fridge`) |
| A to-do or shopping list | `spooligan todo "Call Sam" "Pay rent" -o todo.png` (or `shopping`; `list` takes sections) |
| Wrapped or big text | `spooligan text "Hello **there**" --big -o hello.png` |
| A QR code | `spooligan qr https://example.com caption="Scan me" -o qr.png` |
| A letter, quote or joke | `spooligan message "Thanks for the help" author=Sam -o thanks.png` (or `quote`, `joke`) |
| A meeting or appointment crib sheet | `spooligan crib "Budget review" when="Thu 10:00" -o crib.png` |
| A recipe or how-to | `spooligan preview steps --example recipe` |
| A workout | `spooligan preview workout --example strength` |
| A packing slip | `spooligan preview packing_slip --example cards` |
| A sideways banner | `spooligan banner "Game night" --outline -o banner.png` |
| A header, any blocks and a footer | `spooligan preview doc --example wifi` |

For anything else, write a document: blocks run top to bottom, and a bare string is a paragraph.

```yaml
# file: day.yaml
version: 1
blocks:
  - {type: header, icon: list-checks, kicker: "@todo", meta: true, title: Saturday}
  - {type: checklist, items: [Milk, {text: Eggs, qty: 12}, {text: Bread, done: true}]}
  - {type: kv, rows: {Network: Home, Password: hunter2}}
  - A bare string is a paragraph of **text**.
  - {type: end, text: Have a good day}
```

A document can also come on stdin, which avoids shell quoting:

```sh
spooligan print - -o plan.png <<'EOF'
version: 1
blocks:
  - {type: header, title: "Today's plan"}
  - {type: checklist, items: ["Call the bank", Oat milk]}
EOF
```

`spooligan agents blocks` has every block type, and `spooligan agents templates` covers writing templates of your
own.

## Check before printing

1. `spooligan validate FILE --json` lists every error at once, each with a path, a line and a hint (exit 2).
2. `spooligan print FILE -o FILE.png` (or `spooligan preview FILE`) writes the receipt exactly as it prints. Look at
   it when you aren't sure how it will come out, and show it when the user wants to see it first. Warnings on stderr
   (`warnings` with `--json`) point at things that print badly, such as a QR code too small to scan or a long run of
   solid black.
3. Print when the user asks: `spooligan print FILE`, with `-P NAME` for a printer other than the default.

The exit codes: 0 success, 1 usage, 2 an invalid document or config, 3 the printer, 4 an input file, 5 missing
characters with `--strict`. `spooligan agents json` has the JSON shapes and the full table.

## PNG preview

`-o FILE.png` (or `spooligan preview SRC`) writes the receipt exactly as it prints: 576 or 384 pixels wide, one
pixel per printer dot, black and white. The length in millimetres is the pixel height divided by 8. Use it to:

- check a document before printing it;
- show the user a receipt when they want to see it before it prints;
- compare looks: `-s hand`, `-p 58`, `--tune section=tab`.

```sh
spooligan preview day.yaml                       # writes day.png
spooligan print day.yaml -o day-58.png -p 58 -s hand
spooligan print day.yaml -o day.bin              # the exact bytes a printer would get
```

Each render reports its size, such as `wrote day.png (576×780 dots, 98 mm long)`.

## Topics

This guide is enough for the built-in templates and simple documents. Before other work, read the topic for it.

| Topic | Read it when |
| --- | --- |
| `spooligan agents install` | Installing on a new machine: every build, the macOS installer, Linux USB permissions, Windows |
| `spooligan agents printers` | Setting up or fixing a printer: config files and layers, every printer field, finding a USB or network printer, 58 mm paper |
| `spooligan agents commands` | You need a command or flag this guide doesn't show |
| `spooligan agents documents` | Before writing a document by hand: its fields, text markup, icons and sizes, the fields every block takes, errors and warnings |
| `spooligan agents blocks` | Before using a block type you haven't used: every block, with its fields and an example |
| `spooligan agents templates` | Before writing a template, a shortcut command or an x- block: placeholders, conditions, loops, where they live, pitfalls |
| `spooligan agents locales` | Before adding labels or a language of your own |
| `spooligan agents brands` | Before making a brand kit, the logo and footer for templates such as `packing_slip` |
| `spooligan agents images` | Before printing a photo, logo or other picture, or making custom images for the printer |
| `spooligan agents styles` | When changing the look: styles, legibility tuning, spacing, fonts, other scripts and right-to-left text |
| `spooligan agents studio` | When the user wants to edit a receipt by hand: open it in the studio, give them the link, read it back after |
| `spooligan agents json` | Before parsing `--json` output: the shapes and every exit code |
| `spooligan agents recipes` | For worked examples of common jobs |
| `spooligan agents troubleshooting` | When something fails: symptoms and fixes |
| `spooligan agents --list` | The topics with a one-line summary each (`--json` for a list) |
| `spooligan agents --all` | This guide followed by every topic, in one page |

`spooligan help agents TOPIC` is the same as `spooligan agents TOPIC`.
